我编写了一个 C++ 看门狗,它运行一组脚本来确定该系统是否存在问题。
代码有点繁琐,所以我不会在这里展示,但它相当于一个系统调用,如下所示:
int const r(system("/bin/sh /path/to/script/test-health"));
仅r
当脚本由于if
语句中缺少命令而失败时,才为 0。剧本中有一个令人反感的部分:
set -e
[...]
if unknown_command arg1 arg2
then
[...]
显然unknown_command
失败了,因为……未知。到那时,脚本就结束了,因为我已经set -e
开始了。
但在这种情况下,退出代码将为 0。
在这种情况下我有办法获得退出代码 1 吗?
即问题是检测错误,而不必添加测试来知道是否unknown_command
存在。我知道该怎么做:
if ! test -x unknown_command
then
exit 1
fi
我的观点是,当我编写该脚本时,我期望unknown_command
在我自己安装它时存在,但如果出现问题或有人在另一个系统上复制该脚本而不安装所有内容,我想知道我执行时出错脚本。
答案1
从 POSIX 标准来看,关于set -e
:
当执行、、或保留字
-e
之后的复合列表、以保留字开头的管道或除最后一个 AND-OR 列表的任何命令时,应忽略该设置。while
until
if
elif
!
这意味着在if
语句中执行未知命令将不是导致脚本在运行时终止set -e
。或者更确切地说,set -e
不会导致它终止。
用户command -v
测试 current 中是否存在实用程序PATH
,除非您使用调用的实用程序的完整路径,在这种情况下,测试-x
就足够了,如您的问题所示。
也可以看看: 为什么不用“哪个”呢?那该用什么呢?
答案2
到那时,脚本就结束了,因为我已经
set -e
开始了。
这是一个谎言。
常用脚本:
$ 猫 ./weeble 设置-e 如果摇晃;然后回声摇晃起来。 ;否则回声不会摆动。 ;菲 echo 没有落下。 类型摆动 ||执行错误 执行真 $
您说您知道如何测试未知命令。
Almquist 外壳为/bin/sh
:
$ /bin/sh ./weeble ;回声$? ./weeble:摆动:未找到 没有摇晃。 没有摔倒。 摆动:未找到 1 $ /bin/sh -e ./weeble ;回声$? ./weeble:摆动:未找到 没有摇晃。 没有摔倒。 摆动:未找到 1 $
科恩外壳为/bin/sh
:
$ /bin/sh ./weeble ;回声$? ./weeble[2]:摆动:未找到 没有摇晃。 没有摔倒。 未找到摆动 1 $ /bin/sh -e ./weeble ;回声$? ./weeble[2]:摆动:未找到 没有摇晃。 没有摔倒。 未找到摆动 1 $
Bourne Again shell 为/bin/sh
:
$ /bin/exec -a /bin/sh /usr/local/bin/bash ./weeble ;回声$? ./weeble: 第 2 行: wobble: 未找到命令 没有摇晃。 没有摔倒。 ./weeble:第 4 行:类型:摆动:未找到 1 $ /bin/exec -a /bin/sh /usr/local/bin/bash -e ./weeble ;回声$? ./weeble: 第 2 行: wobble: 未找到命令 没有摇晃。 没有摔倒。 ./weeble:第 4 行:类型:摆动:未找到 1 $
Z 壳为/bin/sh
:
$ /bin/exec -a /bin/sh /usr/local/bin/zsh ./weeble ;回声$? ./weeble:2:找不到命令:摆动 没有摇晃。 没有摔倒。 未找到摆动 1 $ /bin/exec -a /bin/sh /usr/local/bin/zsh -e ./weeble ;回声$? ./weeble:2:找不到命令:摆动 没有摇晃。 没有摔倒。 未找到摆动 1 $
既然你的问题问的是如何避免本来不会发生的事情,并且以谎言为前提和标题,所以它是无法回答的。
答案3
不会if
退出,因为set -e
已经设置了:
#!/bin/sh
set -e
if unknown_command; then
echo "On true, exit code $?"
else
echo "on false, exit code $?"
fi
echo "after if, exit code $?"
打印(在所有测试的 shell 中,带有不同的错误消息):
sh : … : unknown_command: not found
on false, exit code 127
after if, exit code 0
既可以set -e
设置也可以未设置。
如果要检测丢失的命令,请捕获退出代码 127 1:
#!/bin/sh
if unknown_command; then
echo "On true, exit code $?"
else
ec=$?
if [ "$ec" = '127' ]; then
echo "the command failed because it does not exist"
exit 127
fi
echo "on false, exit code $ec"
fi
echo "after if, exit code $?"
它将执行如下:
$ ./script
./script: 5: ./script: unknown_command: not found
the command failed because it does not exist
1
关于退出代码 127
答案4
您应该执行以下两件事之一:
1:
未知命令 arg1 arg2 后续命令
如果失败,将set -e
导致脚本终止unknown_command
。你为什么这么说if
?
2:
如果未知命令 arg1 arg2 然后 后续命令 ︙ 别的 发出错误消息 进行任何所需的清理 1号出口 菲