C'è spesso confusione tra processo di fork ed esecuzione.
Quando lo fai al prompt di una bash
shell.
$ sh -c 'exec env ps'
Il processo P1 che emette quel $
prompt sta attualmente eseguendo il bash
codice. Tale bash
codice genera un nuovo processo P2 che viene /bin/sh
eseguito /usr/bin/env
e quindi eseguito /bin/ps
.
Così P2 è a sua volta il codice di esecuzione bash
, sh
, env
e ps
.
ps
(o qualsiasi altro comando come uno script che utilizzeremo invece qui) non ha modo di sapere che è stato eseguito dal env
comando.
Tutto quello che può fare è scoprire qual è il suo ID di processo genitore, che in questo caso sarebbe P1 o 1
se P1 è morto nell'intervallo o su Linux un altro processo che è stato designato come subreaper anziché 1
.
Può quindi interrogare il sistema per quale comando è attualmente in esecuzione quel processo (come con readlink /proc/<pid>/exe
su Linux) o quali argomenti sono passati all'ultimo comando che ha eseguito (come con ps -o args= -p <pid>
).
Se vuoi che la tua sceneggiatura sappia cosa l'ha invocata, un modo affidabile sarebbe quello di farlo dire al chiamante. Ciò potrebbe essere fatto ad esempio tramite una variabile d'ambiente. Ad esempio script1
potrebbe essere scritto come:
#! /bin/sh -
INVOKER=$0 script2 &
E 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
$INVOKER
conterrà ( generalmente ) un percorso per script1
. In alcuni casi, tuttavia, potrebbe essere un percorso relativo e il percorso sarà relativo alla directory di lavoro corrente al momento script1
dell'avvio. Quindi, se si script1
modifica la directory di lavoro corrente prima di chiamare script2
, script2
si otterranno informazioni errate su ciò che l'ha chiamato. Quindi potrebbe essere preferibile assicurarsi che $INVOKER
contenga un percorso assoluto (preferibilmente mantenendo il nome di base) come scrivendo script1
come:
#! /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
Nelle shell POSIX, $PPID
conterrà il pid del genitore del processo che ha eseguito la shell al momento dell'inizializzazione della shell. Successivamente, come visto sopra, il processo genitore può cambiare se il processo di id $PPID
muore.
zsh
nel zsh/system
modulo di interrogare la corrente pid genitore della shell corrente (sotto-) con $sysparams[ppid]
. Nelle shell POSIX, è possibile ottenere l' attuale ppid del processo che ha eseguito l'interprete (supponendo che sia ancora in esecuzione) con ps -o ppid= -p "$$"
. Con bash
, puoi ottenere il ppid della (sotto-) shell corrente con ps -o ppid= -p "$BASHPID"
.