Bug em como o ksh lida com pipelines?

1

Eu tenho este script simples ( pipecommand.sh ) que imprime um prefixo seguido por seu PID e PPID:

#!/usr/bin/env ksh
echo "$1: PID $$  PPID $PPID" >&2

E esse script que imprime seu PID e PPID e faz um pipe:

#!/usr/bin/env ksh
echo "S: PID $$  PPID $PPID"
./pipecommand.sh A | ./pipecommand.sh B

Quando executo o script, recebo essa saída (simplifiquei os PIDs):

S: PID 11  PPID 22
B: PID 33  PPID 11
A: PID 44  PPID 11

Ok, A e B são ambos filhos do shell. Faz sentido. Embora eu notei que ocasionalmente o pai de A é /sbin/upstart --user (no ubuntu 16.10 pelo menos). Estranho, mas tudo bem.

Mas quando executo o pipe em segundo plano (por exemplo, ./pipecommand.sh A | ./pipecommand.sh B & ), recebo essa saída:

S: PID 11  PPID 22
B: PID 33  PPID 55
A: PID 44  PPID 33

Ok, o pai de B é novato (PID 55). Mas pai de A é B (ou aleatoriamente upstart como antes)? O que está acontecendo? Isso é um bug ou há alguma documentação em algum lugar explicando por que isso acontece? Isso parece especialmente ruim para programas que lidam com o SIGCHLD de uma maneira específica (que é como eu me deparei com esse problema).

Para comparação, em bash A e B são filhos do shell no primeiro caso e filhos do upstart no segundo. Estes resultados parecem consistentes.

ksh --version me dá: version sh (AT&T Research) 93u+ 2012-08-01 .

    
por Kevin 23.03.2017 / 00:41

1 resposta

1

ksh , como o shell Bourne ou yash , quando o não interativo aguarda apenas o comando mais à direita no pipeline. Você notará que:

ksh -c 'sleep 1 | true'

retorna imediatamente para lá.

No seu caso, às vezes, o pai já passou quando A começa e faz um getppid() para preencher a variável $PPID , e você obtém o pid de init ou o subpasme filho que adotou o processo depois que seu pai morreu.

Não é um bug. É por escolha. Fazê-lo dessa maneira, em vez de esperar que cada componente de pipeline tenha suas vantagens (como algum desempenho aprimorado na maioria das situações) e inconvenientes como comportamento inesperado como este ou se os comandos no lado esquerdo do pipeline produzirem resultados que o próximo comando no pipeline script fazer uso de.

    
por 18.08.2017 / 17:30

Tags