Calling theone $var
splits on every word in $var
: the first argument is First
, the second is Argument
, the third is A
, and so on. You will lose your embedded newlines with this approach, and as with any unquoted variable any word in the string that contains a shell wildcard (*
, [
, ]
, ?
) will be subject to globbing and matched against names in the current directory. A string such as "Are you sure??" could be expanded to "Are you surety" if you had a file called surety
in the current directory. Generally, not a good idea.
Based on your previous question I would suggest that's supposed to be written theone "$var"
, where word splitting does not take place and you have a single multi-line argument to theone
.
If you want to process each line of $var
separately I can suggest a number of different constructs. In each, the printf
line is written to show clearly what is being processed in the inner loop. Call each as theone "$var"
:
POSIX
theone()
{
printf '%s\n' "$@" |
while IFS= read -r vl
do
printf '## vl: %s ##\n' "$vl"
done
}
Shells such as bash
theone()
(
for arg in "$@"
do
while IFS= read -r vl
do
printf '## vl: %s ##\n' "$vl"
done <<< "$arg"
done
)
Also shells such as bash
theone()
(
for arg in "$@"
do
readarray -t vls <<<"$arg"
for vl in "${vls[@]}"
do
printf '## vl: %s ##\n' "$vl"
done
done
)
All of these can be simplified by removing the outermost loop if you really only want to pass a single (multi-line) argument. For example, the last one could be written like this:
Shells such as bash
theone()
{
local vls vl
readarray -t vls <<<"$1"
for vl in "${vls[@]}"
do
printf '## vl: %s ##\n' "$vl"
done
}
$@
in the internal loop, otherwise printf '%s\n' "$vl" will split by word. This introduces some confusion. – Vera Feb 19 '23 at 08:40