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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9261397/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 21:39:35  来源:igfitidea点击:

How can I get both the process id and the exit code from a bash script?

bashshell

提问by Bob B

I need a bash script that does the following:

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

  • Starts a background process with all output directed to a file
  • Writes the process's exit code to a file
  • Returns the process's pid (right away, not when process exits).
  • The script must exit
  • 启动一个后台进程,所有输出都指向一个文件
  • 将进程的退出代码写入文件
  • 返回进程的 pid(立即,而不是在进程退出时)。
  • 脚本必须退出

I can get the pid but not the exit code:

我可以得到 pid 但不能得到退出代码:

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

Or, I can capture the exit code but not the pid:

或者,我可以捕获退出代码而不是 pid:

$ executable >>$log;
# blocked on previous line until process exits
echo 
$executable >> $log 2>&1 &
pid=$!
wait $!
echo $?  # return status of $executable
>>$log;

How can I do all of these at the same time?

我怎样才能同时完成所有这些工作?

回答by William Pursell

The pid is in $!, no need to run jobs. And the return status is returned by wait:

pid 在$!,不需要运行jobs。返回状态由 返回wait

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

EDIT 1

编辑 1

If I understand the additional requirement as stated in a comment, and you want the script to return immediately (without waiting for the command to finish), then it will not be possible to have the initial script write the exit status of the command. But it is easy enough to have an intermediary write the exit status as soon as the child finishes. Something like:

如果我理解评论中所述的附加要求,并且您希望脚本立即返回(无需等待命令完成),那么将无法让初始脚本写入命令的退出状态。但是让中介在子进程完成后立即写入退出状态是很容易的。就像是:

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

should work.

应该管用。

EDIT 2

编辑 2

As pointed out in the comments, that solution has a race condition: the main script terminates before the pidfile is written. The OP solves this by doing a polling sleep loop, which is an abomination and I fear I will have trouble sleeping at night knowing that I may have motivated such a travesty. IMO, the correct thing to do is to wait until the child is done. Since that is unacceptable, here is a solution that blocks on a read until the pid file exists instead of doing the looping sleep:

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

##代码##