processo de background do PID

3

Pelo que entendo pipes e comandos, o bash pega cada comando, gera um processo para cada um e conecta o stdout do anterior com o stdin do próximo.

Por exemplo, em "ls -lsa | grep feb", o bash criará dois processos e conectará a saída de "ls -lsa" à entrada de "grep feb".

Quando você executa um comando em segundo plano como "sleep 30 &" no bash, você obtém o pid do processo em segundo plano executando seu comando. Surpreendentemente para mim, quando escrevi "ls -lsa | grep feb &" O bash retornou apenas um PID.

Como isso deve ser interpretado? Um processo executa ambos "ls -lsa" e "grep feb"? Vários processos são criados mas eu só recebo o pid de um deles?

    
por Raul 27.11.2016 / 19:21

2 respostas

2

Gera 2 processos. O & exibe o PID do segundo processo. Exemplo abaixo.

$ echo $$
13358
$ sleep 100 | sleep 200 &
[1] 13405
$ ps -ef|grep 13358
ec2-user 13358 13357  0 19:02 pts/0    00:00:00 -bash
ec2-user 13404 13358  0 19:04 pts/0    00:00:00 sleep 100
ec2-user 13405 13358  0 19:04 pts/0    00:00:00 sleep 200
ec2-user 13406 13358  0 19:04 pts/0    00:00:00 ps -ef
ec2-user 13407 13358  0 19:04 pts/0    00:00:00 grep --color=auto 13358
$
    
por 27.11.2016 / 20:07
3

Quando você executa um trabalho em segundo plano, o bash imprime o ID do processo de seu subprocesso, aquele que executa o comando nesse trabalho. Se esse trabalho criar mais subprocessos, isso não é da conta do shell pai.

Quando o job em background é um pipeline (ou seja, o comando está no formato something1 | something2 & , e não eg { something1 | something2; } & ), há uma otimização que é strongmente sugerida pelo POSIX e executada pela maioria dos shells incluindo o bash: Os elementos do pipeline são executados diretamente como subprocessos do shell original. O que o POSIX exige é que a variável $! esteja definida como o último comando no pipeline neste caso. Na maioria das shells, o último comando é um subprocesso do processo original, assim como os outros comandos no pipeline.

Quando você executa ls -lsa | grep feb , há três processos envolvidos: o que executa o lado esquerdo do canal (um subshell que termina de configurar o canal, em seguida, executa ls ), o que executa o direito lado direito do tubo (um subshell que termina de configurar o tubo, em seguida, executa grep ) e o processo original que aguarda o término do tubo.

Você pode acompanhar o que acontece rastreando os processos:

$ strace -f -e clone,wait4,pipe,execve,setpgid bash --norc
execve("/usr/local/bin/bash", ["bash", "--norc"], [/* 82 vars */]) = 0
setpgid(0, 24084)                       = 0
bash-4.3$ sleep 10 | sleep 20 &
…

Observe como o segundo sleep é relatado e armazenado como $! , mas o ID do grupo de processos é o primeiro sleep . Dash tem a mesma estranheza, ksh e mksh não.

    
por 28.11.2016 / 01:32