编辑这篇文章,原文位于"谢谢!"
下方command='a.out arg1 arg2 &'
eval ${command}
if [ $? -ne 0 ]; then
printf "Command \'${command}\' failed\n"
exit 1
fi
wait
这是一个演示问题的测试脚本,我过于简单了
在原帖中。注意第2行中的&符号和wait命令。
这些更忠实地代表了我的剧本。如果重要,那么&符号
有时在那里,有时不在,它的存在是由用户决定的 -
指定是否为后台长算术的指定标志
计算。而且,如果它很重要,我实际上背景很多
(十二)个过程,即${command[0..11]}
。我想要脚本死了,如果有的话
失败。我用'等待'同步所有进程的成功返回。
快乐(有点)使用另一种方法,但这几乎有效。
&符号(用于背景)似乎会导致问题。
当${command}
省略&符时,脚本按预期运行:
找不到可执行文件a.out,发出了针对该效果的投诉,
和$?非零,因此主机脚本退出。当${command}
包含时
&符号,同样的投诉是发出但是$?是零,所以
脚本继续执行。我希望脚本能够立即死掉
a.out失败但是如何从a获得非零返回值
后台程序?
谢谢!
(原帖):
我有一个使用
形式命令的bash脚本eval ${command}
if [ $? -ne 0 ]; then
printf "Command ${command} failed"
exit 1
fi
其中$ {command}是一串单词,例如" a.out arg1 ... argn"。
问题是来自eval的返回码(即$?
)总是如此
即使${command}
失败,也为零。删除" eval"从上面
snippet允许返回正确的返回码($?
)
停止剧本。我需要将我的命令字符串保存在变量中
(${command}
)以便在其他地方操纵它,并简单地运行
没有评估的${command}
由于其他原因而无法正常工作。我怎么抓住
使用eval时正确的返回码?
谢谢! 查理
答案 0 :(得分:5)
&符号(用于背景)似乎会导致问题。
这是正确的。
在命令完成之前,shell无法知道命令的退出代码。当您在后台放置命令时,shell 不会等待完成。因此,它无法知道后台命令的(未来)返回状态。
man bash
中记录了这一点:
如果命令由控制操作员&,shell终止 在子shell中在后台执行命令。外壳确实如此 不要等待命令完成,返回状态为0。
换句话说,在后台输入命令后的返回码始终为0,因为shell无法预测尚未完成的命令的未来返回码。
如果要在后台查找命令的返回状态,则需要使用wait
命令。
命令false
始终将返回状态设置为1:
$ false ; echo status=$?
status=1
但请注意,如果我们背景会发生什么:
$ false & echo status=$?
[1] 4051
status=0
状态为0,因为命令放在后台,shell无法预测其未来的退出代码。如果我们等一会儿,我们会看到:
$
[1]+ Exit 1 false
在这里,shell正在通知我们完成了背景任务并且它的返回状态正如它应该的那样:1。
在上文中,我们没有使用eval
。如果我们这样做,没有任何改变:
$ eval 'false &' ; echo status=$?
[1] 4094
status=0
$
[1]+ Exit 1 false
如果您确实需要后台命令的返回状态,请使用wait。例如,这显示了如何捕获false
的返回状态:
$ false & wait $!; echo status=$?
[1] 4613
[1]+ Exit 1 false
status=1
答案 1 :(得分:1)
从我系统的手册页:
eval [arg ...] args被读取并连接成一个命令。然后shell读取并执行此命令,并将其退出状态作为eval的值返回。如果没有args或只有null参数,则eval返回0.
如果你的系统文档是相同的,那么,很可能,无论你运行什么命令都是问题,即' a.out'正在回归' 0'在退出而不是非零值。添加适当的退出返回代码'你编译的程序。
你也可以尝试使用$()来运行'你的二进制文件而不是评估'它......,即
STATUS = $(a.out var var var)
只有一个命令'在流中,那么$的值是多少?是退出代码&#39 ;;否则,$?是多命令管道中最后一个命令的返回码' ...
:)
戴尔