如何从另一个Shell会话获取进程退出状态?


7

例如,假设我在一个shell会话中运行一个命令bash -c 'apt-get update && apt-get upgrade'。5分钟后,我决定出门吃点零食,意识到我忘记添加某种形式的通知机制来说明退出是成功还是失败。

好吧,我现在该怎么办?如果我只能从另一个终端查询那个其他命令(或者特别是那个PID)的退出状态,也许我毕竟可以显示某种弹出窗口。所以问题是:如何从另一个终端查询已经运行的进程的退出状态?

换一种说法,

鉴于我在终端A中有一个正在运行的进程,并且它的PID是已知的

当我在终端B中执行某些命令时

然后,我应该能够知道终端A中的过程是否以退出状态0或退出状态> 1完成。


因此,您想在指定的任意进程A(给定的PID)终止后,用命令B附加“观察者”后,运行某种命令(报告退出代码的警报命令?)吗?我们不能假定A是在以后键入B的同一shell中运行的后台作业,不是吗?
字节指挥官

@ByteCommander正确。这是一项前台工作。
Sergiy Kolodyazhnyy

我认为不可能从其他shell的孩子那里获得返回代码。wait终止后,可以使用它在当前shell中获取后台进程的代码,但找不到任何允许查询其他shell的东西。再次简单地监视进程是否仍在运行并在退出时发出警报也很简单,但没有找出其退出代码。我可能想到的唯一方法是,需要准备外壳程序PROMPT_COMMAND以将最后一个退出代码存储在tempfile或类似的可访问位置中。这是一个选择吗?
Byte Commander

@ByteCommander不。无需准备终端A,请完成终端B的所有操作。相信我,这是可能的。
Sergiy Kolodyazhnyy

1
好吧,这将是一个永久性的准备工作(一次编辑.bashrc),但是可以。如果找到答案,期待阅读答案。
字节指挥官

Answers:


8

用法strace如下:

sudo strace -e trace=none -e signal=none -q -p $PID

这里既不涉及系统调用也不涉及信号,因此我们告诉strace您使用-e表达式忽略它们,并使用禁止状态消息-qstrace使用PID附加到进程$PID,等待其正常退出并输出其退出状态,如下所示:

+++ exited with 0 +++

if调用任何类型的通知的简单表达式可以是:

if sudo strace -e trace=none -e signal=none -q -p $PID |& grep -q ' 0 '; then
  echo yeah
else
  echo nope
fi

运行示例

# in terminal 1
$ (echo $BASHPID;sleep 10;true)
8807
# in terminal 2
$ if sudo strace -e{trace,signal}=none -qp8807|&grep -q ' 0 ';then echo yeah;else echo nope;fi
yeah

# in terminal 1
$ (echo $BASHPID;sleep 10;false)
12285
# in terminal 2
$ if sudo strace -e{trace,signal}=none -qp12285|&grep -q ' 0 ';then echo yeah;else echo nope;fi
nope

大部分功劳归功于U&L上的此答案,如果您觉得有用,请留下评论。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.