cygwin 1.7.15在shell脚本中处理“set -e”(子shell中的错误导致父进程退出)

时间:2012-09-13 13:22:50

标签: bash cygwin

我正在使用它:

$ 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退出!那是pID 2880高于我做“set -e”

的地方

这不是Linux或cygwin 1.5.12上的行为。这是cygwin中的cygwin或BASH中的错误吗?

1 个答案:

答案 0 :(得分:0)

这不是错误,它是Bash环境的一个功能。如果您没有设置Bash shell环境变量 execfail ,和/或Shell环境变量 errexit

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的 errexit

set -o errexit

有关详细信息,请参阅:The GNU Bash Manual

PS。 “set”使用反向逻辑,所以如果你想使用'e'标志,你必须使用“+”:set +e