Często występuje pomieszanie między rozwidlaniem procesów a wykonywaniem.
Gdy zrobisz to z polecenia bashpowłoki.
$ sh -c 'exec env ps'
Proces P1 wydający ten $monit aktualnie uruchamia bashkod. Ten bashkod powoduje uruchomienie nowego procesu P2 , /bin/shktóry następnie wykonuje się /usr/bin/env, a następnie wykonuje /bin/ps.
Więc P2 jest z kolei wykonany kod bash, sh, envi ps.
ps(lub jakiekolwiek inne polecenie, takie jak skrypt, którego użylibyśmy tutaj zamiast tego) nie ma sposobu, aby wiedzieć, że zostało ono wykonane przez envpolecenie.
Wszystko, co może zrobić, to dowiedzieć się, jaki jest jego identyfikator procesu nadrzędnego, którym w tym przypadku byłby P1 lub 1gdyby P1 zmarł w tym przedziale czasu, lub w systemie Linux inny proces, który został wyznaczony jako podrzędny zamiast 1.
Następnie może zapytać system o to, jakie polecenie aktualnie wykonuje ten proces (jak readlink /proc/<pid>/exew systemie Linux) lub jakie argumenty zostały przekazane do ostatniego polecenia, które wykonał (jak w przypadku ps -o args= -p <pid>).
Jeśli chcesz, aby skrypt wiedział, co go wywołało, niezawodnym sposobem byłoby, aby wywołujący go powiedział. Można to zrobić na przykład za pomocą zmiennej środowiskowej. Na przykład script1można zapisać jako:
#! /bin/sh -
INVOKER=$0 script2 &
I script2:
#! /bin/sh -
printf '%s\n' "I was invoked by $INVOKER"
# and in this case, we'll probably find the parent process is 1
# (if not now, at least one second later) as script1 exited just after
# invoking script2:
ps -fp "$$"
sleep 1
ps -fp "$$"
exit
$INVOKERbędzie ( ogólnie ) zawierać ścieżkę do script1. W niektórych przypadkach może to być ścieżka względna, a ścieżka będzie względna do bieżącego katalogu roboczego w momencie script1uruchomienia. Więc jeśli script1zmieni bieżący katalog roboczy przed wywołaniem script2, script2otrzyma błędne informacje o tym, co go wywołało. Dlatego może być wskazane, aby upewnić się, że $INVOKERzawiera ścieżkę bezwzględną (najlepiej zachowując basename), na przykład pisząc script1jako:
#! /bin/sh -
mypath=$(
mydir=$(dirname -- "$0") &&
cd -P -- "$mydir" &&
pwd -P) && mypath=$mypath/$(basename -- "$0") || mypath=$0
... some code possibly changing the current working directory
INVOKER=$mypath script2
W powłokach POSIX $PPIDbędzie zawierał pid rodzica procesu, który wykonał powłokę w momencie inicjalizacji tej powłoki. Następnie, jak pokazano powyżej, proces nadrzędny może ulec zmianie, jeśli proces id $PPIDumrze.
zshw zsh/systemmodule może zapytać o bieżący nadrzędny pid bieżącej (pod-) powłoki za pomocą $sysparams[ppid]. W powłokach POSIX można uzyskać bieżący ppid procesu, który wykonał interpreter (zakładając, że nadal działa) ps -o ppid= -p "$$". Za pomocą bashmożna uzyskać ppid bieżącej (pod-) powłoki za pomocą ps -o ppid= -p "$BASHPID".