Как получить статус завершения процесса из другого сеанса оболочки?

7

Предположим, я запускаю команду в одном сеансе оболочки, например bash -c 'apt-get update && apt-get upgrade'. Спустя 5 минут я решил выйти на улицу, чтобы перекусить, и понял, что забыл добавить какой-то механизм уведомления о том, был ли выход успешным или неудачным.

Ну а что мне теперь? Если бы только я мог запросить у другого терминала состояние выхода этой другой команды (или, в частности, этого PID), возможно, я мог бы в конце концов отобразить какое-то всплывающее окно. Итак, вопрос: как я могу запросить состояние выхода уже запущенного процесса с другого терминала?

Другими словами,

ПОДАРОК, что у меня запущен процесс в терминале А, и известен его PID

КОГДА я выполняю какую-то команду в терминале B

ПОТОМ я должен быть в состоянии знать, завершается ли процесс в терминале со статусом выхода 0 или статусом выхода> 1.

Сергей Колодяжный
источник
Итак, вы хотите, чтобы что-то (команда оповещения, сообщающая код выхода?) Запускалось, когда указанный произвольный процесс A (с заданным PID) завершается после присоединения к нему «наблюдателя» с помощью команды B? Мы не можем предполагать, что A является фоновым заданием, выполняющимся в той же оболочке, где вы позже вводите B, нет?
Byte Commander
@ByteCommander Правильно. Это работа на переднем плане.
Сергей Колодяжный
Я не думаю, что возможно получить код возврата от дочернего элемента другой оболочки. Вы можете использовать, waitчтобы получить код фонового процесса в вашей текущей оболочке после его завершения, но я не смог найти ничего, что позволило бы запрашивать другие оболочки. Простой мониторинг того, запущен ли еще какой-либо процесс и вызывает ли предупреждение после его выхода, также тривиально, но не выясняет его код завершения. Единственный способ, который я мог бы придумать, - это подготовить вашу оболочку PROMPT_COMMANDдля хранения последнего кода выхода в временном файле или аналогичном доступном месте. Будет ли это вариант?
Byte Commander
@ByteCommander Нет. Не нужно готовить терминал А, делай все из терминала В. И поверь мне, это возможно.
Сергей Колодяжный,
1
Ну, это была бы постоянная подготовка (редактирование .bashrc один раз), но хорошо. С нетерпением жду, чтобы прочитать ответ, если вы найдете один.
Byte Commander

Ответы:

8

Используйте straceследующим образом:

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

Здесь не интересны ни системные вызовы, ни сигналы, поэтому мы советуем straceигнорировать их с помощью -eвыражений и подавлять сообщение о состоянии с помощью -q. straceприсоединяется к процессу с 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 , пожалуйста, оставьте там отзыв, если вы найдете это полезным.

Десерт
источник