Por que o PIPESTATUS não funciona em pipelines dentro de uma substituição de comando?

3

Prova abaixo: Bash 4

Prompt> $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/')
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0

Prompt> echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/'
Prompt> for i in ${PIPESTATUS[@]}; do echo $i;done
Output> 0
Output> 0
Output> 123
Output> 0

A substituição de comando não é considerada como executada em um shell de primeiro plano? esse é o meu palpite.

    
por Gregg Leventhal 20.08.2014 / 18:43

1 resposta

5

Como a substituição de comandos é executada em subshell, ela não alterou a variável PIPESTATUS do shell pai. Da documentação do Ambiente de Execução de Comando :

Command substitution, commands grouped with parentheses, and asynchronous commands are invoked in a subshell environment that is a duplicate of the shell environment, except that traps caught by the shell are reset to the values that the shell inherited from its parent at invocation. Builtin commands that are invoked as part of a pipeline are also executed in a subshell environment. Changes made to the subshell environment cannot affect the shell’s execution environment.

Você pode obter o resultado esperado se verificar a variável PIPESTATUS no subshell:

$ printf '%s\n' $(echo hello|sed 's/h/m/'|xargs -I{} ls {} 2>/dev/null|sed 's/ /_/';
for i in ${PIPESTATUS[@]}; do echo $i;done)
0
0
123
0
    
por 20.08.2014 / 18:50