#!/bin/bash
function back()
{
sleep $1
exit $2
}
back $1 $2 &
b=$!
if `wait $!`;then
echo success
else
echo failure
fi
bash-3.00# ./back 300 0
failure
bash-3.00# ./back 300 1
failure
当我发送 0 时,我期望success
退出状态,但我仍然收到failure
.
此外,wait
不会等待 300 秒。相反,我会立即收到消息。我假设$!
是脚本中的直接子级$$
。不是吗?
是否可以捕获 wait 之类的退出状态exit_status=$(wait $!)
?
if ! ((exit_status));then
echo sucess
else
failure
fi
答案1
问题是您wait
在子 shell 中发出:
if `wait $!`;then
因为wait
是内置命令,而不是命令,所以它在子外壳,不是您当前的 shell。
您会看到但没有看到的输出是:
wait: pid 12344 is not a child of this shell
...返回状态为 1。
要执行测试,您需要在不使用子 shell 的情况下进行测试。
#!/bin/bash
function back()
{
sleep $1
exit $2
}
back $1 $2 &
b=$!
wait $b && echo success || echo failure
这会给出您期望的结果,并等待您期望的时间:
$ time ./test.sh 3 0
success
./test.sh 3 0 0.00s user 0.01s system 0% cpu 3.012 total
$ time ./test.sh 3 1
failure
./test.sh 3 1 0.00s user 0.01s system 0% cpu 3.012 total
您可以使用以下命令检查任何命令的退出状态$?
:
$ /bin/true
$ echo $?
0
$ /bin/false
$ echo $?
1
您的脚本中还有一些其他错误。你的#!
线路格式错误,我已修复。您分配$!
给$b
,但不使用$b
。
答案2
删除反引号。
现在,您正在wait
子 shell 中执行,该子 shell 无法访问父 shell 的作业,因此它会立即失败。
$?
如果您想要退出状态,请在等待后立即获取值。
command_here &
wait
status=$?
答案3
删除反引号将使程序正常运行,但并不完全是因为已经确定的原因。确实,它wait
会立即失败,因为它在子 shell 中运行,无法访问其父进程,但即使您使用了有效的命令,程序也不会按预期运行。
该if
语句运行一个程序并检查其退出状态是否为零或非零。当您使用反引号时,if 语句将采用输出进程的,尝试将其作为程序运行,然后使用该进程的退出代码。因此,程序并不是因为wait
失败而失败,而是因为wait
没有产生任何输出而失败。
echo
您可以通过在反引号内使用来使脚本工作:
if `echo wait $!`; then
echo success
else
echo failure
fi
或者只是删除反引号;对每个人来说都更容易。