击。恢复后台命令的stderr

时间:2016-05-21 14:28:23

标签: bash background stderr

我在bash脚本中在后台启动命令。我需要在var中恢复它的stderr并且不知道如何。救命! :d

#!/bin/bash
existingdestiny="8.8.8.8" #this is google dns for the example
ping -c 1 $existingdestiny -W 1 > /dev/null 2>&1
exitvar=$?
echo "exitvar: $exitvar"

nonexistingdestiny="172.16.0.234" #this is a non accesible ip example
ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1
exitvar=$?
echo "exitvar: $exitvar"

这样可行,它返回0然后返回1,这是正确的,很好!但如果我把命令放在后台我不能拿stdout。我们来看看:

#!/bin/bash
existingdestiny="8.8.8.8" #this is google dns for the example
ping -c 1 $existingdestiny -W 1 > /dev/null 2>&1 &
exitvar=$?
echo "exitvar: $exitvar"

nonexistingdestiny="172.16.0.234" #this is a non accesible ip example
ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1 &
exitvar=$?
echo "exitvar: $exitvar"

返回0和0,这是不正确的。我怎样才能得到正确的答案?

2 个答案:

答案 0 :(得分:1)

您需要记录后台进程的PID,然后调用wait来收集返回状态。

ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1 &
ping_pid=$!
wait $ping_pid
exitvar=$?
echo "exitvar: $exitvar"

(我想你想要返回状态,而不是文件描述符2上的stderr

答案 1 :(得分:1)

退出代码和标准错误输出(也称为" stderr")是两回事。标准错误输出是一个输出流,任何程序都可以根据需要编写它。退出代码(也称为退出状态)是进程返回的整数。

从问题的片段中,我假设你想要获得退出代码。

特殊的外壳符号$?确实会返回上次启动命令的退出代码。但是,这不适用于在后台通过&启动的命令。这是因为由于命令是在后台启动的,所以还没有完成。即使它已经完成,外壳也不会知道。

要通过&在后台启动命令的退出代码,必须使用wait命令。然后,wait命令的退出代码将完全是等待命令的退出代码。 wait命令将等待后台进程完成。如果后台进程已经终止,则wait命令立即返回。

要使用wait命令,您需要知道后台进程的进程ID。您可以使用$获取在后台启动的命令的进程ID!特殊符号。因此,以下代码将执行您想要的操作:

COMMAND &
pid="$!"
# Optional:  Do something else while ping runs
wait "$pid"
exitcode="$?"
echo "exitcode=$exitcode"

但请注意,ping命令本身不会停止,因此只需在后台启动ping并等待它就会挂起。

我建议不要在后台运行ping。您已正确使用-c和-W选项以确保ping不会挂起。