Cygwin 1.7.15 处理 shell 脚本中的"set -e"(子 shell 中的错误导致父级退出)



我使用的是:

$ uname -a
CYGWIN_NT-6.1 bassoon 1.7.15(0.260/5/3) 2012-05-09 10:25 i686 Cygwin
$ bash --version
GNU bash, version 4.1.10(4)-release (i686-pc-cygwin)
$ cat myexpr.sh
#!/bin/sh
echo "In myexpr, Before  expr"
ac_optarg=`expr x--with-gnu-as : 'x[^=]*=(.*)'`
echo "ac_optarg=$ac_optarg"
echo "In myexpr, After  expr"
$ cat myexpr2.sh
#!/bin/sh
set -e
echo "In myexpr, Before  expr"
ac_optarg=`expr x--with-gnu-as : 'x[^=]*=(.*)'`
echo "ac_optarg=$ac_optarg"
echo "In myexpr, After  expr"

这两个脚本之间的唯一区别是myexpr2.sh使用"set-e"

$ echo $$
2880
$ ./myexpr.sh
In myexpr, Before  expr
ac_optarg=
In myexpr, After  expr
$ ./myexpr2.sh
In myexpr, Before  expr

到目前为止,预期的行为。

如果我在父shell(上面的PID 2880)中执行此操作:

$ set -e
$ ./myexpr.sh

父shell退出!这是pID2880,我在上面做了"set-e"

这不是Linux或cygwin 1.5.12上的行为。这是cygwin中的bug还是cygwin上的BASH?

这不是bug,而是Bash环境的一个特性。当您没有设置Bash-shell环境变量execfail和/或shell环境变量
错误退出时,就会发生这种情况。

execfail - (is a BASHOPTS)
If set, a non-interactive shell will not exit if it cannot execute 
the file specified as an argument to the exec builtin command. 
An interactive shell does not exit if exec fails.
errexit -  (is a SHELLOPTS)
Exit immediately if a pipeline (see Pipelines), which may consist of a 
single simple command (see Simple Commands), a subshell command enclosed 
in parentheses (see Command Grouping), or one of the commands executed as 
part of a command list enclosed by braces (see Command Grouping) returns a 
non-zero status. The shell does not exit if the command that fails is part 
of the command list immediately following a while or until keyword, part 
of the test in an if statement, part of any command executed in a && or || 
list except the command following the final && or ||, any command in a 
pipeline but the last, or if the command’s return status is being inverted 
with !. A trap on ERR, if set, is executed before the shell exits.
This option applies to the shell environment and each subshell environment 
separately (see Command Execution Environment), and may cause subshells to 
exit before executing all the commands in the subshell.

不同的Linux版本有不同的默认值。您可以使用检查哪些已启用

echo "SHELLOPTS=$SHELLOPTS"
echo "BASHOPTS=$BASHOPTS"

你可以看到所有的使用:

set -o && echo -e "n" && shopt -p 

因此,您需要启用您的

shopt -s execfail

如果这不起作用,您可能还必须使用取消设置(关闭)$SHELLOPTS的错误退出

set -o errexit

有关更多信息,请参阅:GNU Bash手册!

PS。"set"使用反向逻辑,因此如果您想使用"e"标志,则必须使用"+":set +e

最新更新