Keen
Keen

Reputation: 2061

Multiline here string yields only one line

I need to process an array of stings in while-do loop, calculate a value and use it outside the loop. At first I wrote this code:

git diff-index --cached HEAD | while read -r LINE; do
   ...
done

but, of course, it doesn't keep inner variable value. Then, I used input redirection, according to advices I've found here:

while read -r LINE; do
...
done <<<$(git diff-index --cached HEAD)

It keeps inner variable value, but there is another problem - the loop is executed only once for the reason I don't understand. I'm quite sure there are more then one line in the input, and the first variant works OK in this respect.

Could someone explain, what is the problem with the second variant, please? Perhaps, I use redirection incorrectly?

Upvotes: 5

Views: 2302

Answers (2)

Martin
Martin

Reputation: 38289

You're on the right track, you only need to put quotes around the output generated by git so that it is properly treated as a single multiline string:

while read -r LINE; do
...
done <<< "$(git diff-index --cached HEAD)"

FWIW, here are some examples to demonstrate the difference quotes will make for a here string:

# "one" is passed on stdin, nothing happens
# "two" and "three" are passed as arguments, and echoed to stdout
$ echo <<< one two three
two three

# "one" is passed on stdin, gets printed to stdout
# "two" and "three" are passed as arguments, cat thinks they are filenames
$ cat <<< one two three 
cat: two: No such file or directory
cat: three: No such file or directory

# "one two three" is passed on stdin
# echo is invoked with no arguments and prints a blank line
$ echo <<< "one two three"

# "one two three" is passed on stdin
# cat is invoked with no arguments and prints whatever comes from stdin
$ cat <<< "one two three"
one two three

Upvotes: 11

choroba
choroba

Reputation: 241858

You are using <<<, which expects a word to be sent to the command. You need

done < <(git ...)

This creates a "file" that is used as the input for read.

Upvotes: 5

Related Questions