Como um processo em segundo plano pode conhecer seu próprio PID?

5

Estou usando o bash em um sistema Linux RH.

Normalmente, você pode obter seu próprio PID com a variável $$. No entanto, se um script executar uma de suas próprias funções como um processo em segundo plano - isso não funciona; todas as funções executadas em segundo plano receberão o PID do script pai quando $$ for usado.

Por exemplo, aqui está um script de teste:

    /tmp/test:
    #!/bin/bash
    echo "I am $$"
    function proce {
      sleep 3
      echo "$1 :: $$"
    }

    for x in aa bb cc; do
      eval "proce $x &"
      echo "Started: $!"
    done

Quando é executado:

    /tmp$ ./test
    I am 5253
    Started: 5254
    Started: 5256
    Started: 5258
    /tmp$ aa :: 5253
    bb :: 5253
    cc :: 5253

Então - o script pai (/ tmp / test) é executado como PID 5253 e dispara três processos em segundo plano com os PIDs 5254, 5256 e 5258. Mas cada um desses processos em segundo plano obtém o valor 5253 com $$.

Como esses processos podem descobrir seu PID real?

    
por Ron 02.04.2015 / 21:05

2 respostas

9

$BASHPID pode ser o que você está procurando.

BASHPID

Expands to the process ID of the current Bash process. This differs from $$ under certain circumstances, such as subshells that do not require Bash to be re-initialized.

Em oposição a $$

($$) Expands to the process ID of the shell. In a () subshell, it expands to the process ID of the invoking shell, not the subshell.

link

    
por 02.04.2015 / 21:08
6

com bash :

echo "$BASHPID"

daria o pid do processo que avalia o comando echo

Note que (por exemplo, após um enable -n echo ) não é necessariamente o mesmo que o pid do processo que está executando esse comando echo .

bash (ou qualquer shell) faz sua própria sopa com processos. Nem sempre é útil tentar adivinhar que processo faz o quê.

$ readlink -f /proc/self "/proc/$BASHPID"
/proc/30868
/proc/30747
$ (readlink -f /proc/self "/proc/$BASHPID")
/proc/30869
/proc/30869

Nesse segundo caso, readlink é executado no mesmo processo que interpretou a linha de comando porque esse é o último comando executado nessa sub-rotina (portanto, bash otimiza um fork() ).

O zsh equivalente está no módulo zsh/system :

$ zmodload zsh/system
$ echo $$ $sysparams[pid]
5155 5155
$ (echo $$ $sysparams[pid])
5155 30979

( zsh também expõe o pid pai do subshell em $sysparams[ppid] ).

Portavelmente, você pode fazer:

pid=$(sh -c 'echo "$PPID"')

Todos os shells devem executar esse sh como um filho direto da subshell interpretando essa linha de comando, para que sh ' $PPID seja a subcamada.

    
por 02.04.2015 / 22:07