跳到主要内容

返回与退出

bash 脚本中可以通过返回(return)和退出(exit)来终止执行流程,其中 return 只能出现在函数中和source加载的脚本中,用于退出函数或代码块;exit 可以存在于任何地方,用于退出进程。return 和 exit 都能产生指定的返回值,不指定默认为最后一个命令的返回值, 0代表成功, 非0代表异常。

写出一段在正常情况下可以运行的脚本相对容易,但是要写出一段更加健壮的、能应对各种异常情况的脚本就非常讲究,这需要不断的经验积累以及正确的异常处理机制。

返回值

脚本中命令执行完成后会有一个返回值,取值为0-255,在不使用 return 或 exit 指定返回值的情况下,函数和脚本的返回值是最后一个命令的返回值。返回值存储在一个特殊的变量 $? 中,$?只会记录最后一个命令的返回值,我们可以通过将此变量的值复制到其他变量来保存指定命令的返回值。例如:

date
echo $?

date
retval=$?
echo $retval

返回

下面看一个例子:

test_return() {
    date
    data
}
test_return

上面脚本执行的返回值是127,即最后一个命令data的返回值,因为命令无效所以返回了非0值,下面是自定义返回值:

test_return() {
    date
    data
    return 0
}
test_return

这时函数的返回值就是自定义的0。

退出

接着看一个退出的例子:

test_return() {
    date
    exit 66
}
test_return
echo $?

执行上面这段脚本后,最后一行的echo $?并不会执行到,因为函数中使用了exit,而函数的执行是在此脚本的运行进行中进行的,所以当 exit 触发了进程退出时后面的内容也就不会执行了。所以当函数执行完还有其他逻辑需要执行时,切忌不要使用exit而应该用return

那么问题来了,上面的这个函数有没有办法不改变exit又不影响后续的执行呢?可以试试将函数放到子进程中执行,类似(test_return)这样用括号括起来的内容会被放到子进程中,当exit时只会退出子进程而不影响主进程。