3

Proof below: 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

Is command substitution not considered to be run in a foreground shell? that's my guess.

5

Because the command substitution is run in subshell, so it made no change to the PIPESTATUS variable of the parent shell. From Command Execution Environment documentation:

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.

You can get the expected result if you check the PIPESTATUS variable in the 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
  • That's what I thought. I wanted to assign a variable with command substitution using a pipeline, and take action if any element of PIPESTATUS was != 0. I ended up skipping command substitution and using read VAR < <(pipeline) to work around it. – Gregg Leventhal Aug 20 '14 at 20:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.