Posix Shell 设置 -e 时测试非零退出代码脚本终止
Posix Shell test non zero exit code script termination when set -e
阅读test
shell命令的手册:
man test
描述状态:
Exit with the status determined by EXPRESSION.
但这与我的 POSIX sh 测试脚本示例冲突,我在其中使用 set -eu
如果命令的退出状态不为零,则应终止脚本:
#!/bin/sh
set -eu
status=1
test "$status" -ne 0 && echo "Status not eq 0"
echo "(A) Exit code for "$status" = $?"
echo ""
status=0
test "$status" -ne 0 && echo "Status not eq 0"
echo "(B) Exit code for "$status" = $?"
echo ""
status=1
test "$status" -ne 0
echo "(C) Exit code for "$status" = $?"
echo ""
status=0
test "$status" -ne 0
echo "(D) Exit code for "$status" = $?"
运行宁该脚本提供输出:
Status not eq 0
(A) Exit code for 1 = 0
(B) Exit code for 0 = 1
(C) Exit code for 1 = 0
这就是我对执行流程的理解:
status=1
test "$status" -ne 0 && echo "Status not eq 0"
echo "(A) Exit code for "$status" = $?"
输出:
Status not eq 0
(A) Exit code for 1 = 0
test "$status" -ne 0
的计算结果为真,因此它的退出代码为零,因此执行布尔值 &&
之后的表达式,因为它只是一个 echo
,它也 returns退出代码为零,因此脚本不会中断并回显下一行 (A) Exit code for 1 = 0
但是对于
status=0
test "$status" -ne 0 && echo "Status not eq 0"
echo "(B) Exit code for "$status" = $?"
输出:
(B) Exit code for 0 = 1
根据前面的推理,test
应该 return 非零,因此不应执行 &&
之后的表达式(事实并非如此),但脚本甚至会执行 test
returned 非零退出代码 (B) 0 = 1.
的退出代码
为什么脚本会继续执行?由于非零退出状态,它应该制动。
案例没有输出:
status=0
test "$status" -ne 0
echo "(D) Exit code for "$status" = $?"
这对我来说表明脚本执行在行 test "$status" -ne 0
处终止,如果你 运行 echo $?
在 运行 脚本之后你实际上会得到1
.
但是当测试 returns 示例的非零退出状态 (D) 但它不是示例 (B)?
(D)和(B)的唯一区别是(B) 在测试后有 && echo "Status not eq 0"
但未执行并且退出状态为 1
所以在 (B) 的情况下脚本应该终止但它没有't 如果测试的退出状态以某种方式如此特殊地处理,因此它不会终止具有 set -e
的脚本,那么为什么它会终止 (D) 示例的脚本?
编辑
类似于 test
的行为 ls
对于脚本:
#!/bin/sh
set -eu
ls notexitingfile && echo "File exists"
echo "Exit code for ls = $?"
ls notexitingfile
echo "Exit code for ls = $?"
输出为:
ls: cannot access 'notexitingfile': No such file or directory
Exit code for ls = 2
ls: cannot access 'notexitingfile': No such file or directory
注意第一个例子 Exit code for ls = 2
,第二个例子没有。
我认为意外行为的原因可能是我对脚本终止的误解 (set -e
) 由于使用 &&
运算符时非零退出代码。
set -e 选项仅适用于单个命令。
它不适用于与 || 组合的命令或 &&.
男人 bash 说:
如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、紧跟在 if 或 elif 保留字之后的测试的一部分、执行的任何命令的一部分,则 shell 不会退出在 && 或 || 中列出除最后一个 && 或 || 之后的命令之外的列表,管道中除最后一个命令之外的任何命令,或者如果命令的 return 值被 !.
反转
阅读test
shell命令的手册:
man test
描述状态:
Exit with the status determined by EXPRESSION.
但这与我的 POSIX sh 测试脚本示例冲突,我在其中使用 set -eu
如果命令的退出状态不为零,则应终止脚本:
#!/bin/sh
set -eu
status=1
test "$status" -ne 0 && echo "Status not eq 0"
echo "(A) Exit code for "$status" = $?"
echo ""
status=0
test "$status" -ne 0 && echo "Status not eq 0"
echo "(B) Exit code for "$status" = $?"
echo ""
status=1
test "$status" -ne 0
echo "(C) Exit code for "$status" = $?"
echo ""
status=0
test "$status" -ne 0
echo "(D) Exit code for "$status" = $?"
运行宁该脚本提供输出:
Status not eq 0
(A) Exit code for 1 = 0
(B) Exit code for 0 = 1
(C) Exit code for 1 = 0
这就是我对执行流程的理解:
status=1
test "$status" -ne 0 && echo "Status not eq 0"
echo "(A) Exit code for "$status" = $?"
输出:
Status not eq 0
(A) Exit code for 1 = 0
test "$status" -ne 0
的计算结果为真,因此它的退出代码为零,因此执行布尔值 &&
之后的表达式,因为它只是一个 echo
,它也 returns退出代码为零,因此脚本不会中断并回显下一行 (A) Exit code for 1 = 0
但是对于
status=0
test "$status" -ne 0 && echo "Status not eq 0"
echo "(B) Exit code for "$status" = $?"
输出:
(B) Exit code for 0 = 1
根据前面的推理,test
应该 return 非零,因此不应执行 &&
之后的表达式(事实并非如此),但脚本甚至会执行 test
returned 非零退出代码 (B) 0 = 1.
为什么脚本会继续执行?由于非零退出状态,它应该制动。
案例没有输出:
status=0
test "$status" -ne 0
echo "(D) Exit code for "$status" = $?"
这对我来说表明脚本执行在行 test "$status" -ne 0
处终止,如果你 运行 echo $?
在 运行 脚本之后你实际上会得到1
.
但是当测试 returns 示例的非零退出状态 (D) 但它不是示例 (B)?
(D)和(B)的唯一区别是(B) 在测试后有 && echo "Status not eq 0"
但未执行并且退出状态为 1
所以在 (B) 的情况下脚本应该终止但它没有't 如果测试的退出状态以某种方式如此特殊地处理,因此它不会终止具有 set -e
的脚本,那么为什么它会终止 (D) 示例的脚本?
编辑
类似于 test
的行为 ls
对于脚本:
#!/bin/sh
set -eu
ls notexitingfile && echo "File exists"
echo "Exit code for ls = $?"
ls notexitingfile
echo "Exit code for ls = $?"
输出为:
ls: cannot access 'notexitingfile': No such file or directory
Exit code for ls = 2
ls: cannot access 'notexitingfile': No such file or directory
注意第一个例子 Exit code for ls = 2
,第二个例子没有。
我认为意外行为的原因可能是我对脚本终止的误解 (set -e
) 由于使用 &&
运算符时非零退出代码。
set -e 选项仅适用于单个命令。 它不适用于与 || 组合的命令或 &&.
男人 bash 说:
如果失败的命令是紧跟在 while 或 until 关键字之后的命令列表的一部分、紧跟在 if 或 elif 保留字之后的测试的一部分、执行的任何命令的一部分,则 shell 不会退出在 && 或 || 中列出除最后一个 && 或 || 之后的命令之外的列表,管道中除最后一个命令之外的任何命令,或者如果命令的 return 值被 !.
反转