我有一个shell脚本,用于检查Windows行结尾。
set -e
(! git ls-files | xargs grep -I $'\r')
我使用!
字符来否定命令的返回码。当找到带回车符的文件时,Grep将返回代码0
,然后!
否定返回代码的值为1
并退出脚本。与grep
(无xargs
)一起使用时,这不带括号。使用xargs
时,根据$?
进行否定,因为echo $?
会打印1
,但脚本不会退出!在整个命令周围添加括号后,它按预期工作。为什么需要括号?
答案 0 :(得分:6)
您的问题与-e
无关。
bash的while
选项有点棘手。
-e 如果管道(可能包含 单个简单命令),列表或复合命令 ,以非零退出 状态。 如果命令那么shell不会退出 failed是立即命令列表的一部分 遵循
until
或if
关键字,是测试的一部分 遵循elif
或&&
保留字,部分内容 除命令外,在||
或&&
列表中执行的命令 在最后的||
或!
之后,任何命令都在 管道但最后一个,或如果命令返回 价值与$ cat exit_on_error_test.sh #!/bin/bash trap 'echo Interrupted because of an error' ERR set -e ! true echo Exit status: $? $ ./exit_on_error_test.sh Exit status: 1 $
相反。
让我们看一个更简单的例子:
! true
因此,即使“! true
”的退出状态为非零,也允许脚本运行到结尾并输出退出状态的值。那是因为我们没有任何失败的命令 - 非零退出代码是由于故意否定。
但是,如果我们在括号中加上“$ cat exit_on_error_test.sh
#!/bin/bash
trap 'echo Interrupted because of an error' ERR
set -e
(! true) # This as a whole is now a failing (compound) command
echo Exit status: $?
$ ./exit_on_error_test.sh
Interrupted because of an error
$
”,我们会引入一个失败的(复合)命令。
.container {
display: flex;
flex-flow: row wrap;
}
.header {
min-height: 60px;
border: 1px solid #000;
}
.list {
height: 100%;
display: flex;
justify-content: flex-start;
list-style: none;
margin: 0;
padding: 0;
}
li {
padding: 10px;
background-color: #cecece;
}
答案 1 :(得分:1)
set -e
命令指示
如果命令以非零状态退出,则立即退出
(见help set
)。
在Bash中,括号中的表达式创建subshell(子进程),其工作方式类似于单个命令。因此,如果子shell退出时出现错误代码,则父脚本也会退出(由于-e
设置)。
因此,如果grep
找到\r
字符,则子shell以非零状态退出;主脚本也退出此代码(由于set -e
)。
您的问题的答案为什么需要括号?是:因为您可能想要退出主脚本,如果grep
在其中一个字符中找到\r
字符git控制下的文件。