如何从bash脚本中获取进程ID和退出代码?

时间:2012-02-13 13:30:03

标签: bash shell

我需要一个执行以下操作的bash脚本:

  • 启动后台进程,所有输出都指向文件
  • 将进程的退出代码写入文件
  • 返回进程的pid(立即返回,而不是在进程退出时)。
  • 脚本必须退出

我可以获得pid而不是退出代码:

$ executable >>$log 2>&1 &
pid=`jobs -p`

或者,我可以捕获退出代码,但不能捕获pid:

$ executable >>$log;
# blocked on previous line until process exits
echo $0 >>$log;

我怎样才能同时做所有这些?

1 个答案:

答案 0 :(得分:56)

pid位于$!,无需运行jobs。返回状态由wait返回:

$executable >> $log 2>&1 &
pid=$!
wait $!
echo $?  # return status of $executable

编辑1

如果我理解了注释中所述的附加要求,并且您希望脚本立即返回(无需等待命令完成),那么将无法让初始脚本写入退出状态命令。但是,一旦孩子完成,让中间人写出退出状态就很容易了。类似的东西:

sh -c "$executable"' & echo pid=$! > pidfile; wait $!; echo $? > exit-status' &

应该有用。

编辑2

正如评论中指出的那样,该解决方案具有竞争条件:主脚本在写入pidfile之前终止。 OP通过进行轮询睡眠循环来解决这个问题,这是一种令人厌恶的事情,我担心我会在晚上睡觉时遇到麻烦,因为我知道我可能有这种讽刺的动机。 IMO,正确的做法是等到孩子完成。由于这是不可接受的,这里有一个解决方案,阻止读取直到pid文件存在而不是循环睡眠:

{ sh -c "$executable > $log 2>&1 &"'
echo $! > pidfile
echo   # Alert parent that the pidfile has been written
wait $!
echo $? > exit-status
' & } | read