Bash heredoc 的回显损坏

Bash corrupted echo for heredoc

这是我的脚本:

#!/bin/bash

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

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

没有行 {cron":"0 1 * * *"} 它完美地工作并产生正确的输出:

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

但第 {cron":"0 1 * * *"} 行打印出损坏的输出:

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

我 运行 这个脚本 macOS

编辑:正确的方法是使用 while-loop 而不是 for-loop。查看其他答案。

“for line”-循环在白色处分裂space。第一个不需要的 whitespace 是 cron 行中“0”和“1”之间的 space。输出中的“垃圾”是脚本的命令行参数?至少我的测试看起来是这样。

为避免在白色处分裂space,请使用变量 IFS。将其设置为“换行符”。

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

编写此脚本的正确方法是 while 循环。

while IFS= read -r line; do
    printf '%s\n' "$line"
done <<'EOF'
one
two
three
{"foo":"bar"}
{cron":"0 1 * * *"}
EOF

最起码不需要read设置content的值:

content='one
two
three
{"foo":"bar"}
{cron":"0 1 * * *"}'

但是使用 for 循环遍历文件充满了问题。参见 How can I read a file (data stream, variable) line-by-line (and/or field-by-field)? and Why you don't read lines with "for"