2012-09-13 30 views
0

我使用這個:Cygwin的1.7.15處理的shell腳本「設置-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 

到目前爲止的預期行爲。

如果我這樣做的母貝(PID 2880,以上):

$ set -e 
$ ./myexpr.sh 

父shell退出!這是上面的pID 2880,我在其中設置了「-e」

這不是Linux或cygwin 1.5.12上的行爲。這是cygwin或BASH上cygwin的錯誤嗎?

+0

預期的行爲是'ac_optarg'有一個空值?我認爲你的'expr'命令有問題,這會使'set -e'放棄第二個腳本。 – chepner

+0

嗨,是的,預期的行爲是ac_optarg將爲空,因爲正則表達式不會成功。這種不常見的行爲是當我在父shell中設置「-e」時,父shell退出。如果我在父shell中設置「-e」並執行myexpr.sh(爲了安全起見,我還將exit 0添加到最後一行),父shell將退出。僅在1.7g的cygwin上 –

回答

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取消(off):

set -o errexit 

欲瞭解更多信息,請參閱:The GNU Bash Manual

PS。 「set」是使用反向邏輯,所以如果你想使用'e'標誌,你必須使用「+」:set +e