Bash Process Substituição na linha exec, alguns comandos pararam de funcionar

1

Portanto, eu tenho um comando bash usando a substituição de processos em uma linha exec que parou de funcionar recentemente e resume-se a este exemplo:

Conteúdo do script.sh:

#!/bin/bash   
ls -l "$1" >/tmp/out  
echo "SUCCESS" > "$1"

Isso funciona, colocando "SUCCESS" em log :

rm -f log; ./script.sh >(cat >log)

Usar tail também funciona:

rm -f log; ./script.sh >(tail >log)

Usando exec com cat works:

rm -f log; exec ./script.sh >(cat >log)

Mas ... exec com tail NÃO funciona:

rm -f log; exec ./script.sh >(tail >log)

Em todos os casos, o conteúdo de / tmp / out parece bem, parecendo algo como:

l-wx------ 1 user user 64 Oct 14 10:55 /dev/fd/63 -> pipe:[158518]

Por que cat funciona, mas não tail ou head ? Isso estava funcionando em algum momento no passado .. isso é uma mudança de recurso bash ou regressão de bug ..?

bash --version: GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
    
por Erik 14.10.2016 / 20:13

1 resposta

0

Portanto, usar strace no processo substituído revelou que tail e head estavam obtendo um SIGHUP do kernel antes que tivessem uma chance de escrever. Uma solução simples é adicionar nohup à substituição:

rm -f log; exec ./script.sh >(nohup tail >log)

Acho que entendo por que isso falha com exec. O IIUC, > (tail > log) cria um processo filho do processo atual bash . No entanto, quando se usa exec, agora se torna um processo filho de script.sh . Quando script.sh sai, o kernel envia SIGHUP para todos os processos-filhos.

Ainda não sei por que isso costumava funcionar, talvez em versões mais recentes do kernel seja mais rápido / mais agressivo em enviar seus SIGHUPs.

    
por 15.10.2016 / 00:10