obtendo lista de processos filhos por uma função shell de fundo

1

Eu tenho um script bash, no qual chamo função em segundo plano:

process_manager $1 $2 $3 &

A função executa / executa comandos que são passados como um argumento em segundo plano.

Como posso obter uma lista de processos filhos na função process_manager?

Eu tentei fazer isso:

process_manager () {
  count=$1
  interval=$2
  cmd=$3
  bash_pid=$$
  last_pid=$!

  echo "bash_pid: $bash_pid, ppid: $PPID, last_pid: $last_pid"
  $cmd &
  $cmd &
  sleep 30 &
}

process_manager $1 $2 $3 &
process_manager $1 $2 $3 &
process_manager $1 $2 $3 &

Mas aqui a função process_manager não exibe $! ou $ last_pid quando é chamado pela primeira vez.

Como devo obter $ last_pid nessa situação e poder acessar a lista de processos de crianças?

    
por Aljaz 25.05.2014 / 14:59

1 resposta

3

$$ 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.

    
por 25.05.2014 / 22:11