bashnewlineherestring

Processing output command with new lines redirected as Herestring


I'm dealing with a while loop processing a Herestring input:

one_is_achieved=0
while IFS="=" read key value ; do
  process_entry key value && one_is_achieved=1
done <<<$(output_entries)
# Dealing with one_is_achieved
[...]

the function output_entries() outputs key-values lines:

k1=some stuff
k2=other stuff
k3=remaining stuff

Problem, the command subtitution $() captures stdout but replace ends of line by spaces, causing k1 entry to be some stuff k2=other stuff k3= remaining stuff.

Is there a way to prevent the replacement or to restore the ends of lines?


Note: I solved my problem this way:

while IFS="=" read key value ; do
  process_entry key value && one_is_achieved=1
done < <(output_entries)

But I think the original question is still relevant (preserving or restoring end of lines).


Solution

  • It is how command substitution is implemented in bash shell. The $(..) in unquoted form removes any embedded newlines because of the default word-splitting done by the shell. The default IFS value is $' \t\n' and unquoted expansion causes the splitting to happen based on any of these 3 characters.

    You need to quote the substitution to prevent the word-splitting from happening. From the GNU bash man page or reset the IFS value by setting IFS="" before the substitution is expanded.

    $(command)

    Bash performs the expansion by executing command in a subshell environment and replacing the command substitution with the standard output of the command, with any trailing newlines deleted. Embedded newlines are not deleted, but they may be removed during word splitting.