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.