Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2349640
  • 博文数量: 527
  • 博客积分: 10343
  • 博客等级: 上将
  • 技术积分: 5565
  • 用 户 组: 普通用户
  • 注册时间: 2005-07-26 23:05
文章分类

全部博文(527)

文章存档

2014年(4)

2012年(13)

2011年(19)

2010年(91)

2009年(136)

2008年(142)

2007年(80)

2006年(29)

2005年(13)

我的朋友

分类:

2005-09-05 09:20:12

BASH脚本可以以 . 或 source内置命令来执行, 也可以直接执行脚本文件(需要首行有#!/path/to/bash并且文件是可执行的), 这两种情况是有一些微妙区别的.

1. 以.或source这两个等价的builtin来执行脚本时是在当前的SHELL解释器中直接读取命令来执行, 所以可以通过这个脚本改变当前SHELL的环境变量, 脚本中的exit所退出的也自然是当前这个SHELL, 这一点很可能不是大多数情况下的预期行为. 而直接执行脚本则会在一个子SHELL进程中读取脚本中的命令执行, 此时只能改变当前这个进程的环境变量, 不能上溯影响其父进程的环境块, 而exit也只是退出这个子进程而已. 在程序刚开始的地方往往会检查参数的合法性, 如果参数个数, 顺序或其它方面的要求不正确, 程序往往就没办法执行, 此时最经常的用法就是显示程序的usage信息, 然后用exit 1;来提前终止程序. 但这对于用.或source执行脚本的情况来说就会错误地退出当前的shell, 怎么样在任何情况下都能让程序全身而退: SHLVL 变量, 它是shell level的简写. 意思是SHELL被嵌套的次数.
[ ! -f $1 ] && { echo "FILE $1 doesn't exist"; [ $SHLVL -gt 1 ] && exit 1; [ $SHLVL -eq "1" ] && return; }
上面这个命令检查了$1 是否是一个普通文件, 如果不是就显示一条错误信息说该文件不存在, 然后检查 $SHLVL是否大于1, 如果是的话就可以安全地用exit退出, 此时后面那句话也就不必执行了, 如果不是的那它的值其实也只能是1了(这个变量是SHELL中的只读变量, 不能以可编程的方法来改变), 这时说明是在当前的shell执行的, 用return;语句退出.

那么是不是两种情况都可以简单地用return; 来退出呢. 不是!
简单地执行下面的脚本(tmp.sh)
#!/bin/bash

{
  return;
}
echo "After return";

如果是以. tmp.sh来执行就没问题, 如果以./tmp.sh来执行则会显示一条错误信息:
./tmp.sh: line 5: return: can only `return' from a function or sourced script
说的很明白, return只能用在直接解释执行的脚本或函数中. 上面的{ ... }只是一个命令组, 不是函数(不要认为是个匿名函数)

在很多的程序语言里, return也的确只能用于函数的返回, 在SHELL编程中它也可以出现在程序最外面层的位置. 只不过这种用法只对所谓sourced 脚本才有特殊语意.
标准的SHELL内置帮助是没有提及这个特殊用法的, 反而前面的错误信息提到了这一点:
bash-2.05b$ help return
return: return [n]
    Causes a function to exit with the return value specified by N.  If N
    is omitted, the return status is that of the last command.

阅读(1727) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~