我在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,这是不正确的。我如何才能得到正确的回答?
退出代码和标准错误输出(也称为"stderr")是两种不同的东西。标准的错误输出是一个输出流,任何程序都可以向它写入它想要的任何内容。退出代码(也称为退出状态)是进程返回的整数。
根据问题中的片段,我假设您想要获得退出代码。
特殊的外壳符号$?将返回上次启动的命令的退出代码。但是,这不适用于通过&在后台启动的命令;。这是因为由于该命令是在后台启动的,因此尚未完成。即使它完成了,外壳也不会知道。
为了通过&获得在后台启动的命令的退出代码;,您必须使用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不会挂起。
您需要记录后台进程的PID,然后调用wait
来收集返回状态。
ping -c 1 $nonexistingdestiny -W 1 > /dev/null 2>&1 &
ping_pid=$!
wait $ping_pid
exitvar=$?
echo "exitvar: $exitvar"
(我想您想要的是返回状态,而不是文件描述符2上的stderr
)。