0

I'm looking at some old scripts and I found some parameter assignment that I have not seen before. A while loop reads from a text file and passes the values to a function. The items in the text file look like this:

user_one:abcdef:secretfolder

the first stage of the function then looks like this:

 IFS=':' read -a param <<< $@

 user="${param[0]}"
 pass="${param[1]}"
 user_folders="${param[2]}"

I have not seen this sort of assignment before and was wondering if this is just an alternative way of handling it. Is the above the same as this?

IFS=':' read -a param <<< $@

user="${1}"
pass="${2}"
user_folders="${3}"

(change in values to 1-3 due to ${0} being the name of the file itself). This script is 5 years old; This original sort of assignment just seems a longer way to to it, unless I've missed something

I'm still learning shell scripting but as I understand, setting IFS=':' will split the fields on : rather than whitespace and so in the examples, the value of "${param[0]}" and ${1} passed to the function would be user_one

Can someone please explain if there is a reason why "${param[0]}" should be used instead of ${1}?

scrow
  • 357
  • 3
  • 13
  • 2
    `IFS=':' read -a param <<< $@` is creepy!! Unless the author wants to remove all `\ ` from `$@`, trim all leading & ending spaces, convert all space+ to single space and mix up the arguments of the function, then the correct command would be `IFS=':' read -ra param <<< "$1"` – Fravadona Apr 13 '22 at 11:28
  • there are multiple lines on the file that is being read if that wasn't obvious. So there are about 10 users each on a new line. So would $@ be ok to use in this case as it will take in all the users? – scrow Apr 13 '22 at 12:56
  • @scrow you may want to show a minmal example: few sample lines from the file (making sure to include a line that includes a few users on the same line), the `while` loop (reading from the file), and the actual function call; processing a line like `a:b:c` is going to be different from processing a line like `a:b:c g:h:i m:n:o x:y:z`; also note that `func_call a:b:c` is processed differently from `IFS=: func_call a:b:c` ... point being that it may help to see a bit more of the data and code – markp-fuso Apr 13 '22 at 14:55

1 Answers1

1

The command:

IFS=':' read -a param <<< $@

reads the :-separated fields from the command arguments ($@) into the array variable named param. Bash arrays work just like lists in other languages, and you index them with brackets. ${param[0]} is the first field, ${param[1]} then next, and so on. Arrays like this can contain anything, and it's just because of the $@ in the read command that this param array happens to contain the arguments. It could just as easily contain foo, bar, and baz if it were created like:

param=(foo bar baz)

The ${1}, ${2} etc. syntax always refers to the script arguments though.

Pi Marillion
  • 4,465
  • 1
  • 19
  • 20