5

While trying the cat "$@" trick to read from either standard input or given files, it turned out that pipe and process substitution handle a missing trailing newline differently:

printf %s foo > test.txt

unset REPLY
while read
do
    :
done < <(cat test.txt)
echo "$REPLY" # Prints foo

unset REPLY
cat test.txt | while read
do
    :
done
echo "$REPLY" # Prints nothing!

Is this by design? Is this "feature" documented anywhere?

D'oh! @fered had the right idea - It's just another example of how variable values are lost because piped commands are run in a subshell.

1
  • Only in ATT ksh (ksh88 and ksh93, but not pdksh) and in zsh does the right-hand side of a pipe run in the parent shell. Commented Oct 26, 2011 at 7:28

1 Answer 1

11

Variables in a pipe never make it out of the pipe alive :)
Process substitution redirects the data to a file descriptor. Behind the scenes, that process is not the same as a | pipe. The following works, because it is all within the same pipe.

unset REPLY
cat test.txt | { 
  while read ;do : ;done
  echo "$REPLY" 
} # Prints foo!

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.