Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

'read -ra' vs direct assignment

Tags:

bash

shell

In a bash (version 3) script, I want to save the passed command line arguments, so that I can iterate over them several times (with shift) and potentially strip out some of them.

From what I understand, the "$@" is like an array in the first place.

My first impulse is to write:
cmdArgs="$@"
and then manipulate cmdArgs as any other array.

However, I am reading a lot of answers where another syntax is used:
read -ra cmdArgs <<<"$@"

Why? The second option is longer, less obvious in what it does, but seems to be the preferred choice. So why?

like image 722
Slav Avatar asked Feb 11 '23 10:02

Slav


1 Answers

Neither is correct. Both try to use "$@" correctly, but each uses it in a context where the resulting list of words is collapsed into a single whitespace-separated string before you can access the individual elements.

The first assigns the string to a regular variable, not an array.

$ set "foo bar" baz
$ cmdArgs="$@"
$ printf "%s\n" "$cmdArgs"
foo bar baz

The second uses the <<< operator, which only takes a single word, so read gets a single whitespace-separated string and splits it into a list of-separated, so that an argument containing whitespace is split into multiple array elements.

$ read -ra cmdArgs <<< "$@"
$ printf "%s\n" "${cmdArgs[@]}"
foo
bar
baz

The correct method is

$ cmdArgs=( "$@" )
$ printf "%s\n" "${cmdArgs[@]}"
foo bar
baz
like image 177
chepner Avatar answered Feb 13 '23 22:02

chepner