Search code examples
bashshechoheredoc

Bash corrupted echo for heredoc


Here my script:

#!/bin/bash

read -r -d '' content << VAR
one
two
three
{"foo":"bar"}
{cron":"0 1 * * *"}
VAR

for line in $content; do
  echo "==| ${line}"
done

without line {cron":"0 1 * * *"} it works perfectly and produces correct output:

==| one
==| two
==| three
==| {"foo":"bar"}

but with line {cron":"0 1 * * *"} it prints corrupted output:

==| one
==| two
==| three
==| {"foo":"bar"}
==| {cron":"0
==| 1
==| LICENSE
==| README.md
==| ed
==| y.sh
==| LICENSE
==| README.md
==| ed
==| y.sh
==| *"}

I'm running this script on macOS.


Solution

  • Edit: The correct way is to use a while-loop instead of a for-loop. See other answers.

    The "for line"-loop splits at whitespace. The first unwanted whitespace is the space in cron line between "0" and "1". The "junk" in the output are the script's command line arguments? At least my tests look like they are.

    To avoid splitting at whitespace, use the variable IFS. Set it to "newline".

    IFS=$'\n'
    read -r -d '' content << VAR
    one
    two
    three
    {"foo":"bar"}
    {"cron":"0 1 * * *"}
    VAR
    for line in $content; do
      echo "==| ${line}"
    done