Muitas vezes há confusão entre bifurcação e execução de processos.
Quando você faz no prompt de um bash
shell.
$ sh -c 'exec env ps'
O processo P1 que emite esse $
prompt está atualmente executando o bash
código. Esse bash
código bifurca um novo processo P2 que executa /bin/sh
e /usr/bin/env
depois executa /bin/ps
.
Então P2 , por sua vez código executado bash
, sh
, env
e ps
.
ps
(ou qualquer outro comando como um script que usaríamos aqui) não tem como saber que foi executado pelo env
comando.
Tudo o que você pode fazer é descobrir qual é o ID do processo pai, que nesse caso seria P1 ou 1
se P1 morreu no intervalo ou no Linux outro processo que foi designado como subreader em vez de 1
.
Em seguida, ele pode consultar o sistema para saber qual comando esse processo está executando atualmente (como readlink /proc/<pid>/exe
no Linux) ou quais argumentos foram passados para o último comando executado (como com ps -o args= -p <pid>
).
Se você deseja que seu script saiba o que o invocou, uma maneira confiável seria pedir ao invocador. Isso pode ser feito, por exemplo, através de uma variável de ambiente. Por exemplo, script1
poderia ser escrito como:
#! /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
( geralmente ) conterá um caminho para script1
. Em alguns casos, pode ser um caminho relativo, e o caminho será relativo ao diretório de trabalho atual no momento em que foi script1
iniciado. Portanto, se script1
alterar o diretório de trabalho atual antes de ligar script2
, script2
obterá informações erradas sobre o que o chamou. Portanto, pode ser preferível garantir que $INVOKER
o caminho seja absoluto (de preferência mantendo o nome da base), escrevendo script1
como:
#! /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
Nos shells POSIX, $PPID
conterá o pid do pai do processo que executou o shell no momento da inicialização do shell. Depois disso, como visto acima, o processo pai pode mudar se o processo de identificação $PPID
morrer.
zsh
no zsh/system
módulo, pode consultar o actual pid pai do reservatório actual (sub) com $sysparams[ppid]
. Nos shells POSIX, você pode obter o ppid atual do processo que executou o intérprete (assumindo que ele ainda esteja em execução) com ps -o ppid= -p "$$"
. Com bash
, você pode obter o ppid do (sub) shell atual com ps -o ppid= -p "$BASHPID"
.