Abstract:
A "filename expansion" safe solution (for my-script2):
IFS=' ' read -a arr <<<"$1"
printf '<%s>--' "${arr[@]}" ; echo
The naive solution of using the variable un-quoted to get it divided into words (based on IFS value) also expose the contents to filename expansion on *, ? and [ (at least).
This specific string works correctly:
$ set "a string with spaces"
$ printf '<%s>--' $1; echo
<a>--<string>--<with>--<spaces>--
But this string clearly fails:
$ set "a bad * string with spaces"
$ printf '<%s>--' $1; echo
<a>--<bad>--<file1>--<file2>--<string>--<with>--<spaces>--
The asterisk got expanded into the files in PWD.
Here-doc
One way (very often overlooked but also very useful) to get variable expansion without "pathname expansion" is to use a here-document.
IFS=' ' read -ra arr <<-_EOF_
$1
_EOF_
printf '<%s>--' "${arr[@]}" ; echo;
As explained in the manual:
If word is unquoted, all lines of the here-document are subjected to parameter expansion, command substitution, and arithmetic expansion, … …
Please note that "pathname expansion" is not applied.
The cousin of a here-document is the here-string, which makes the code shorter:
IFS=' ' read -ra arr <<<"$1"
printf '<%s>--' "${arr[@]}" ; echo;
Just remember that (as inside double quotes) the characters \, $, and ` are special.
From the manual:
the character sequence \ is ignored, and \ must be used to quote the characters \, $, and `
./my-script1 "$@"
so in my-script, $1 is a string of arguments, separated by whitespace" is false, so actually I don't know what you're asking. – Michael Homer Jul 15 '17 at 02:14set -f; my-script $1
? – Jeff Schaller Jul 15 '17 at 02:43