C'è spesso confusione tra processo di fork ed esecuzione.
Quando lo fai al prompt di una bashshell.
$ sh -c 'exec env ps'
Il processo P1 che emette quel $prompt sta attualmente eseguendo il bashcodice. Tale bashcodice genera un nuovo processo P2 che viene /bin/sheseguito /usr/bin/enve quindi eseguito /bin/ps.
Così P2 è a sua volta il codice di esecuzione bash, sh, enve ps.
ps(o qualsiasi altro comando come uno script che utilizzeremo invece qui) non ha modo di sapere che è stato eseguito dal envcomando.
Tutto quello che può fare è scoprire qual è il suo ID di processo genitore, che in questo caso sarebbe P1 o 1se 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>/exesu 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 script1potrebbe 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
$INVOKERconterrà ( 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 script1dell'avvio. Quindi, se si script1modifica la directory di lavoro corrente prima di chiamare script2, script2si otterranno informazioni errate su ciò che l'ha chiamato. Quindi potrebbe essere preferibile assicurarsi che $INVOKERcontenga un percorso assoluto (preferibilmente mantenendo il nome di base) come scrivendo script1come:
#! /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, $PPIDconterrà 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 $PPIDmuore.
zshnel zsh/systemmodulo 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".