Linux 中的 wait 命令用法?

Linux 中的 wait 命令用法?
#!/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

或者只是删除反引号;对每个人来说都更容易。

相关内容