Jak uzyskać status wyjścia z procesu z innej sesji powłoki?

7

Załóżmy na przykład, że uruchamiam polecenie w jednej sesji powłoki bash -c 'apt-get update && apt-get upgrade'. 5 minut później postanawiam wyjść na przekąskę i zdaję sobie sprawę, że zapomniałem dodać mechanizmu powiadamiania o tym, czy wyjście było sukcesem, czy porażką.

Co mam teraz zrobić? Gdybym tylko mógł zapytać z innego terminala o status wyjścia tego innego polecenia (a konkretnie tego PID), może mógłbym mimo wszystko wyświetlić jakieś wyskakujące okienko. Pytanie brzmi: w jaki sposób mogę sprawdzić status wyjścia już uruchomionego procesu z innego terminala?

Innymi słowy,

PODAJĄC, że mam uruchomiony proces w terminalu A ORAZ jego PID jest znany

KIEDY wykonuję jakieś polecenie w terminalu B

Następnie powinienem wiedzieć, czy proces w terminalu A kończy się ze statusem wyjścia 0 lub statusem wyjścia> 1.

Sergiy Kolodyazhnyy
źródło
Więc chcesz, aby coś (komenda alertowa zgłaszająca kod zakończenia?) Działała po zakończeniu określonego, dowolnego procesu A (podanego PID) po dołączeniu do niego „obserwatora” za pomocą komendy B? Nie możemy założyć, że A jest zadaniem w tle działającym w tej samej powłoce, w której później wpisujesz B, prawda?
Bajt Dowódca
@ByteCommander Poprawnie. To praca na pierwszym planie.
Sergiy Kolodyazhnyy
Nie sądzę, że można uzyskać kod powrotu od dziecka innej powłoki. Możesz użyć, waitaby uzyskać kod procesu działającego w tle w bieżącej powłoce po jej zakończeniu, ale nie mogłem znaleźć niczego, co pozwalałoby na zapytanie innych powłok. Samo monitorowanie, czy proces nadal działa i generowanie alertu po jego zakończeniu, jest znowu trywialne, ale nie znajduje kodu wyjścia. Jedyny sposób, jaki mogłem wymyślić, wymagałby przygotowania powłoki PROMPT_COMMANDdo przechowywania ostatniego kodu wyjścia w pliku tymczasowym lub w podobnej dostępnej lokalizacji. Czy to byłaby opcja?
Bajt Dowódca
@ByteCommander Nope. Bez przygotowywania terminalu A, rób wszystko od terminalu B. I zaufaj mi, to możliwe.
Sergiy Kolodyazhnyy
1
Cóż, byłoby to stałe przygotowanie (jednorazowa edycja .bashrc), ale dobrze. Czekamy na odpowiedź, jeśli ją znajdziesz.
Byte Commander

Odpowiedzi:

8

Użyj stracew następujący sposób:

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

Żadne wywołania systemowe ani sygnały nie są tu interesujące, więc mówimy, straceaby zignorować je -ewyrażeniami i ukryć komunikat o statusie za pomocą -q. stracedołącza się do procesu z PID $PID, czeka, aż zakończy się normalnie i wysyła swój status wyjścia w następujący sposób:

+++ exited with 0 +++

Prostym ifwyrażeniem wywołującym dowolne powiadomienie może być:

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

Przykładowy przebieg

# 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

Większość zasług pochodzi z tej odpowiedzi w U&L , proszę zostawić tam głosowanie, jeśli uznasz to za przydatne.

deser
źródło