Home > Enterprise >  Why does '<<<' in Bash works only when a command is executed?
Why does '<<<' in Bash works only when a command is executed?

Time:12-29

If I run the first command, it outputs a="A", b="B", but if I run the second command, it doesn't output anything.

first

while read a && read b; do echo "a=$a, b=$b"; done <<<$(echo '["A", "B"]' | jq '.[]')

second

 while read a && read b; do echo "a=$a, b=$b"; done <<<"A B"

Why can't I read the string supplied unless it comes from a command output?

CodePudding user response:

In the second example, read a consumes the entire here string. read b has nothing left to read, so it fails. This causes the while loop condition to fail, which means the body is never executed.

The difference in the first command is that jq produces two lines of output, so each read command reads one of them. (The newlines separating them is preserved because the result of the command substitution is not subject to word-splitting, as the value of the here string.)

$ echo '["A", "B"]' | jq '.[]'
"A"
"B"

CodePudding user response:

That's not what's happening here. Your second attempt produces a single line, which is consumed by the first read; the second read then fails, which causes it to return an error, which causes while to not enter the loop.

The proper solution would look something like

while read -r a b; do
    echo "a='$a' b='$b'"
done <<<'"A" "B"'

and, for that matter, your first attempt should probably not use <<< at all;

while read -r a && read -r b; do
    echo "a='$a' b='$b'"
done < <(echo '["A", "B"]' | jq '.[]')

or

echo '["A", "B"]' | jq '.[]' |
while read -r a && read -r b; do
    echo "a='$a' b='$b'"
done

The <<< here-string syntax really only makes sense to use when what you have is actually already a string. Use a pipe or a process substitution to read something from a subprocess.

  • Related