Reputation: 411
From man bash
:
If the -c option is present, then commands are read from
the first non-option argument command_string. If there
are arguments after the command_string, the first argument
is assigned to $0 and any remaining arguments are assigned
to the positional parameters. The assignment to $0 sets the
name of the shell, which is used in warning and error messages.
I don't understand the purpose of the $0
assignment.
I was exploring ways to pass arguments to multiple commands with xargs. The following solution works just fine (inspired from here), but I fail to understand why an argument is needed at the end :
[ Edit : following chepner's answer, the argument doesn't need to be empty, it can be anything indeed, but it has to exist ].
$ cat test
abc
def
ghi
$ cat test | xargs -n 1 /bin/bash -c 'echo "1-$@"; echo "2-$@";' 'dummyArgument'
1-abc
2-abc
1-def
2-def
1-ghi
2-ghi
Obviously the 'dummyArgument'
is necessary for bash -c
to be able to interpret $@
, (it can even be empty ''
) because without it I get the following result :
$ cat test | xargs -n 1 /bin/bash -c 'echo "1-$@"; echo "2-$@";'
1-
2-
1-
2-
1-
2-
But how does it work ? Why do I need that 'dummyArgument'
?
Upvotes: 2
Views: 442
Reputation: 530882
It doesn't have to be empty quotes (which is how you provide an empty string as a concrete value). It can be any value, if you don't actually care about the value of $0
in your command. If you do care, then you would provide the value you want instead of an empty string.
But whatever the first argument is, it will be used to set $0
. There is no option to leave $0
unset and apply the arguments to $1
et al intead.
Other common "dummy" values are _
, sh
, and bash
.
An easy way to see the difference between an empty argument and no argument is to use the set
command, then look at the value of $#
. First, no positional arguments:
$ set --
$ echo "$#"
0
Now, a single empty argument
$ set -- ''
$ echo "$#"
1
Upvotes: 2
Reputation: 50750
I don't understand the purpose of the
$0
assignment.
Its purpose is to let you give your inline script a name, potentially for decorating diagnostic messages. There is nothing interesting about it.
$ cat foo.sh
echo my name is $0
$
$ bash foo.sh a b c
my name is foo.sh
$
$ bash -c 'echo my name is $0' foo a b c
my name is foo
Upvotes: 2