You have no list variable in your code. You have a string.
The call to test1
uses the expansion $letterList
unquoted. This will make the shell split its value up into multiple words on spaces, tabs and newline characters (by default), and each word will undergo filename globbing (if they contain filename globbing characters). The resulting words are passed to test1
as separate arguments.
In test1
, you only put the very first of these arguments into letterList
.
If you want to pass the string in $letterList
as it is to test1
from test2
, you need to double quote its expansion in the call:
test1 "$letterList"
Incidentally, you rely on the shell performing the splitting of the $letterList
value in your loop in test1
(the same mechanics that cause your issue), but you never protect the code from accidentally performing filename globbing (test your script with e.g. test2 "A B C *"
to see what I mean).
If you want to pass a list rather than a single string, then call test2
with a list rather than with a string:
test2 A B C "Hello World" "* *"
Then, in test2
, pass the arguments to test1
:
#!/bin/sh test1 "$@"
Here, "$@"
will expand to the list of positional parameters (the arguments to the script), with each individual parameter being quoted. This means that an argument like Hello World
will not be split into multiple arguments in the call to test1
, and the string * *
will also not get split up into two and no filename globbing will occur.
In test1
, iterate over the arguments:
#!/bin/sh for arg in "$@"; do printf '%s\n' "$arg" done
or
#!/bin/sh for arg do printf '%s\n' "$arg" done
... or, if you just want to print the arguments, just
#!/bin/sh printf '%s\n' "$@"
I've used /bin/sh
as the shell throughout as there is nothing here that is specific to bash
.
test2
replace last line with./test1 "$letterlist"
" "
does the trick. The addition of `.` threw me an error. I assume that it is not necessary since without it it works.