9

Suppose I run a command in one shell session, for example bash -c 'apt-get update && apt-get upgrade'. 5 minutes later I decide to go outside for a snack, and realize I forgot to add some form of notification mechanism for whether exit was success or failure.

Well, what do I now ? If only I could query from another terminal the exit status of that other command ( or specifically, that PID), maybe I could after all display some sort of pop up. So the question is: how can I query exit status of an already running process from another terminal ?

In other words,

GIVEN that I have a running process in terminal A AND its PID is known

WHEN I execute some command in terminal B

THEN I should be able to know if process in terminal A finishes with exit status 0 or exit status >1.

  • So you want something (an alert command reporting the exit code?) to run once a specified, arbitrary process A (given PID) terminates, after attaching a "watcher" to it with command B? We can not assume that A is a background job running in the same shell where you later type B, no? – Byte Commander Sep 3 '18 at 23:29
  • @ByteCommander Correct. It's a foreground job. – Sergiy Kolodyazhnyy Sep 3 '18 at 23:32
  • I don't think it is possible to get a return code from a child of a different shell. You can use wait to get the code of a background process in your current shell, after it terminates, but I could not find anything that would allow querying other shells. Simply monitoring whether a process is still running and raising an alert once it exits is also trivial again, but not finding out its exit code. The only way I could possibly think of would require preparing your shell's PROMPT_COMMAND to store the last exit code in a tempfile or similar accessible location. Would that be an option? – Byte Commander Sep 3 '18 at 23:49
  • @ByteCommander Nope. No preparing terminal A, do everything from terminal B. And trust me, it's possible. – Sergiy Kolodyazhnyy Sep 4 '18 at 0:01
  • 1
    Well, it would be a permanent preparation (editing .bashrc once), but okay. Looking forward to read the answer, if you find one. – Byte Commander Sep 4 '18 at 0:03
8

Use strace as follows:

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

Neither system calls nor signals are of interest here, so we tell strace to ignore them with the -e expressions and supress a status message with -q. strace attaches to the process with PID $PID, waits for it to exit normally and outputs its exit status like this:

+++ exited with 0 +++

A simple if expression to call any type of notification could be:

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

Example run

# 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

Most of the credit goes to this answer on U&L, please leave an upvote there if you find this useful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.