第六章:退出和退出状态

 

...there are dark corners in the Bourne shell, and people use all of them.

 Chet Ramey

exit命令一般用于结束一个脚本,就像C语言的exit一样。它也能返回一个值给父进程。

每一个命令都能返回一个退出状态(有时也看做返回状态).一个命令执行成功返回0,一个执行不成功的命令则返回一个非零值,此值通常可以被解释成一个对应的错误值。除了一些例外的情况,一个行为端庄的UNIX命令,程序或是软件包执行成功能返回0的作为退出码。

同样的,在脚本里的函数和脚本自身都会返回一个退出状态码。在脚本或函数里被执行的最后一个命令将决定退出状态码。在一个脚本里,exit nnn 命令将会返回shell一个nnn的退出状态码。(nnn必须是一个在0-255范围的十进制整数)。

如果一个脚本以不带参数的exit命令结束,脚本的退出状态码将会是执行exit命令前的最后一个命令的退出码。

   1 #!/bin/bash
   2 
   3 COMMAND_1
   4 
   5 . . .
   6 
   7 # 脚本将会以最后命令COMMAND_LAST的状态码退出。
   8 COMMAND_LAST
   9 
  10 exit

脚本结束没有exit,不带参数的exitexit $?三者是等价的。

   1 #!/bin/bash
   2 
   3 COMMAND_1
   4 
   5 . . .
   6 
   7 # 会以最后命令的退出码退出脚本.
   8 COMMAND_LAST
   9 
  10 exit $?

   1 #!/bin/bash
   2 
   3 COMMAND1
   4 
   5 . . . 
   6 
   7 # 会以最后命令的退出码退出脚本.
   8 COMMAND_LAST

$?变量保存了最后一个命令执行后的退出状态。当一个函数返回时,$?保存了函数里最后一个命令的退出状态码。这就是Bash里函数返回值的处理办法。当一个脚本运行结束,$? 变量保存脚本的退出状态,而脚本的退出状态则是脚本中最后一个已执行命令的退出状态。并且依照惯例,0表示执行成功,1-255的整数范围表示错误。


例子 6-1. 退出/退出状态码

   1 #!/bin/bash
   2 
   3 echo hello
   4 echo $?    # 因为上一条命令执行成功,打印0.
   5 
   6 lskdf      # 无效命令.
   7 echo $?    # 因为上面的无效命令执行失败,打印一个非零的值.
   8 
   9 echo
  10 
  11 exit 113   # 返回113状态码给shell.
  12            # 可以运行脚本结束后立即执行命令"echo $?" 检验.
  13 
  14 #  依照惯例,命令'exit 0'表示执行成功,
  15 #+ 当产生一个非零退出值时表示一个错误或是反常的条件。

$? 变量用于测试脚本中的命令执行结果非常的有用(参考例子 12-32例子 12-17).

逻辑非操作符!反转一个命令或一个测试的结果,它也能反转退出状态.


例子 6-2. 逻辑非一个条件结果的用法

   1 true  # ture命令是内建的.
   2 echo "exit status of \"true\" = $?"     # 0
   3 
   4 ! true
   5 echo "exit status of \"! true\" = $?"   # 1
   6 # 注意逻辑非字符"!"需要一个空格.
   7 #    !true   会导致一个"command not found"(命令没有发现)的错误。
   8 #
   9 # 操作符'!'放在一个命令前面会导致调用Bash的历史机制。
  10 
  11 true
  12 !true
  13 # 这次没有错误,也没有反转结果.
  14 # 它只是重复执行上次的命令(true).
  15 
  16 # 多谢, Stéphane Chazelas and Kristopher Newsome.

有一些退出状态码被用于保留(reserved meanings) 的含义,不应该在用户脚本使用。