0

我正在使用这个:

$ 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

父外壳退出!那就是上面我做了“set -e”的pID 2880

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

4

1 回答 1

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 的错误退出

set -o errexit

有关详细信息,请参阅:GNU Bash 手册

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

于 2013-01-16T04:29:13.450 回答