$$
contém o pid do shell que foi executado para interpretar o script . É o mesmo em cada subcama desse shell.
$!
contém o pid do último comando filho executado em segundo plano (com &
ou coproc ou substituição de processo)
No comando executado em segundo plano, $!
não está definido. $!
é destinado ao pai para que ele possa esperar ou matar seu filho.
bash
tem uma variável $BASHPID
que contém o pid da sub-shell atual .
Nem sempre é claro qual é o processo.
Em:
echo "$BASHPID"
É o pid do processo que interpretou o comando echo
, mas em
/bin/echo "$BASHPID"
que bifurca um processo, $BASHPID
não reporta o pid daquele processo bifurcado, mas o pid do pai. Enquanto em:
/bin/echo "$BASHPID" &
(a única diferença é que o pai não espera por seu filho), $BASHPID
informa o pid do processo bifurcado:
$ bash -c 'echo "$$"; echo "$BASHPID"; /bin/echo "$BASHPID"; /bin/echo $BASHPID &'
3264
3264
3264
3266
No seu caso, você pode fazer isso com segurança:
process_manager () {
pid_of_last_command_run_in_background=$!
mypid=$BASHPID
cmd &
cmd1pid=$!
cmd &
cmd2pid=$!
}
$pid_of_last_command_run_in_background
será o pid do último comando executado em segundo plano (pelo subshell atual, ou seu pai ou seu avô). É por isso que você obtém algo em $last_pid
na segunda execução (o pid do process_manager anterior) e não na primeira.