putting "$@" in variable

21 views
Skip to first unread message

Stefan W

unread,
Dec 1, 2021, 8:46:32 AM12/1/21
to
Hi! I'm writing very ordinary script. It processes some standard list of
files being called with no arguments, and it handles passed files if
there are arguments. Nothing strange.

I'm know that correct iteration of list of arguments in bash could be
simple as:

for i in "$@"; do
echo $i
done

being called like:

> ./test.sh 1 2 '3 4'

it gives correct output

1
2
3 4

But if I put in into variable, things got worse:

files="$@"

for i in $files; do
echo $i
done

> ./test.sh 1 2 '3 4'

1
2
3
4

I know that it is possible to use `if` and iterate with `for arg in
"$@";`. But I want to have only one universal algorithm for file
processing, and just prepare a list of files and then pass it to function.

How could I have correct list of filenames (probably containing spaces)
in correctly iterable variable in bash?

Janis Papanagnou

unread,
Dec 1, 2021, 9:42:34 AM12/1/21
to
On 01.12.2021 14:46, Stefan W wrote:
> Hi! I'm writing very ordinary script. It processes some standard list of
> files being called with no arguments, and it handles passed files if
> there are arguments. Nothing strange.
>
> I'm know that correct iteration of list of arguments in bash could be
> simple as:
>
> for i in "$@"; do
> echo $i
> done
>
> [...]
>
> But if I put in into variable, things got worse:
>
> files="$@"
>
> for i in $files; do
> echo $i
> done
>
> [...]
>
> I know that it is possible to use `if` and iterate with `for arg in
> "$@";`. But I want to have only one universal algorithm for file
> processing, and just prepare a list of files and then pass it to function.
>
> How could I have correct list of filenames (probably containing spaces)
> in correctly iterable variable in bash?

Assigning to simple scalar variables make the program parameters flat,
that's hardly avoidable.

If you want to keep an existing array structure intact then use shell
arrays as in

files=( "$@" )

for i in "${files[@]}"; do
echo $i
done


Janis

Spiros Bousbouras

unread,
Dec 1, 2021, 10:04:39 AM12/1/21
to
Surely that should be echo "$i"

Janis Papanagnou

unread,
Dec 1, 2021, 4:38:42 PM12/1/21
to
On 01.12.2021 16:04, Spiros Bousbouras wrote:
> On Wed, 1 Dec 2021 15:42:29 +0100
> Janis Papanagnou <janis_pa...@hotmail.com> wrote:
>> On 01.12.2021 14:46, Stefan W wrote:
>>> [...]
>>
>> files=( "$@" )
>>
>> for i in "${files[@]}"; do
>> echo $i
>> done
>
> Surely that should be echo "$i"

I considered that just as test output and left it unchanged,
but surely you are right to better have a correctly quoted
paragon and quote it anyway, I agree. My fault.

Janis

glenn stevenson

unread,
Mar 27, 2022, 6:42:37 PMMar 27
to
here's a worked example .... - use quotes to avoid any potential shell expansion

for file in 1 2 3 '3 4'; do x="${file}";echo "<${x}>"; done
<1>
<2>
<3>
<3 4>

Janis Papanagnou

unread,
Mar 27, 2022, 7:03:46 PMMar 27
to
This is a bad example - what happens if you omit the quotes here?

$ for file in 1 2 3 '3 4' ; do x=${file} ; echo +${x}+ ; done
+1+
+2+
+3+
+3 4+

The variables ${file] and ${x} are still correctly expanded.

As a maybe better example, below the quotes around ${x} are necessary:

$ for file in 1 2 3 '3 4'; do x=${file}; printf "'%s'\n" "${x}"; done

Of course, to demonstrate the expansion, this suffices:

$ for x in 1 2 3 '3 4'; do printf "'%s'\n" "${x}"; done

since the assignment x=${file} doesn't need quotes and can be omitted
for the example.

Janis

Geoff Clare

unread,
Mar 29, 2022, 8:41:08 AMMar 29
to
Janis Papanagnou wrote:

> On 28.03.2022 00:42, glenn stevenson wrote:

>> here's a worked example .... - use quotes to avoid any potential shell expansion
>>
>> for file in 1 2 3 '3 4'; do x="${file}";echo "<${x}>"; done
>> <1>
>> <2>
>> <3>
>> <3 4>
>>
>
> This is a bad example - what happens if you omit the quotes here?
>
> $ for file in 1 2 3 '3 4' ; do x=${file} ; echo +${x}+ ; done
> +1+
> +2+
> +3+
> +3 4+
>
> The variables ${file] and ${x} are still correctly expanded.

Nit-pick: +${x}+ is not correctly expanded, it's just that the behaviour
of echo with multiple arguments hides the problem because it produces
the same output. (As you point out later, this can be avoided by
doing such tests with printf instead of echo.)

--
Geoff Clare <net...@gclare.org.uk>
Reply all
Reply to author
Forward
0 new messages