简体   繁体   中英

What's the purpose of the argument at the end of "bash -c command argument"?

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' ?

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM