A menudo hay confusión entre la bifurcación del proceso y la ejecución.
Cuando lo haces en el indicador de un bash
shell.
$ sh -c 'exec env ps'
El proceso P1 que emite ese $
indicador está ejecutando actualmente el bash
código. Ese bash
código bifurca un nuevo proceso P2 que se ejecuta /bin/sh
y luego se ejecuta /usr/bin/env
, que luego se ejecuta /bin/ps
.
Así P2 a su vez ha ejecutado el código de bash
, sh
, env
y ps
.
ps
(o cualquier otro comando como un script que usaríamos aquí) no tiene forma de saber que ha sido ejecutado por el env
comando.
Todo lo que puede hacer es averiguar cuál es su ID de proceso principal, que en este caso sería P1 o 1
si P1 ha muerto en el intervalo o en Linux otro proceso que se ha designado como un subárea en lugar de 1
.
Luego puede consultar al sistema qué comando está ejecutando ese proceso actualmente (como con readlink /proc/<pid>/exe
Linux) o qué argumentos pasaron al último comando que ejecutó (como con ps -o args= -p <pid>
).
Si desea que su script sepa qué lo invocó, una forma confiable sería que el invocador lo dijera. Eso podría hacerse, por ejemplo, a través de una variable de entorno. Por ejemplo, script1
podría escribirse como:
#! /bin/sh -
INVOKER=$0 script2 &
Y 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
( generalmente ) contendrá una ruta a script1
. Sin embargo, en algunos casos, puede ser una ruta relativa, y la ruta será relativa al directorio de trabajo actual en el momento en que script1
comenzó. Entonces, si script1
cambia el directorio de trabajo actual antes de llamar script2
, script2
obtendrá información incorrecta sobre lo que lo llamó. Por lo tanto, puede ser preferible asegurarse$INVOKER
contenga una ruta absoluta (preferiblemente manteniendo el nombre base) como escribiendo script1
:
#! /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
En los depósitos POSIX, $PPID
contendrá el pid del padre del proceso que ejecutó el shell en el momento de la inicialización de ese shell. Después de eso, como se vio anteriormente, el proceso padre puede cambiar si el proceso de identificación $PPID
muere.
zsh
en el zsh/system
módulo, puede consultar el actual pid matriz de la cáscara de corriente (sub-) con $sysparams[ppid]
. En shells POSIX, puede obtener el ppid actual del proceso que ejecutó el intérprete (suponiendo que todavía se esté ejecutando) ps -o ppid= -p "$$"
. Con bash
, puede obtener el ppid del actual (sub) shell con ps -o ppid= -p "$BASHPID"
.