I\'d like to know the best way of using positional parameters when using the command bash -c
.
The man pages indicates for the -c
option tha
bash -c 'printf "%s %s %s\n" $0 $1 $2' param1 param2 param3
The above works but many would consider it a bad habit to get into. If you were to copy code from the -c
string to a script, it would fail. Similarly, if you were to copy code from a script to a -c
string, it would fail.
By contrast, with the following form, $1
means the same thing in the -c
string that it would mean in a script or shell function:
bash -c 'printf "%s %s %s\n" $1 $2 $3' _ param1 param2 param3
Consistency of programming style reduces bugs.
$0
differentlyOne customarily refers to all of a script's arguments with $@
or $*
. Note that these variables do not include $0
:
$ bash -c 'echo "$*"' param1 param2 param3
param2 param3
$ bash -c 'echo "$@"' param1 param2 param3
param2 param3
$0
is the program nameIn regular scripts, $0
is the name of the script. Consequently, when using bash -c
, some people prefer to use some meaningful name for the $0
parameter, such as:
bash -c 'printf "%s %s %s\n" $1 $2 $3' bash param1 param2 param3
Or:
bash -c 'printf "%s %s %s\n" $1 $2 $3' printer param1 param2 param3
This approach has a clear advantage if the -c
string generates an error. For example, consider this script:
$ cat script.sh
#!/bin/bash
bash -c 'grepp misspelling "$1"' BadPgm file.txt
If we run the script, the following output is produced:
$ ./script.sh
BadPgm: grepp: command not found
This identifies the source of the error as the command in the bash -c
string.
The parameter $0
is special in that it does not participate in shift
(for example).
This works as expected:
$ bash -c 'shift; printf "%s %s %s\n" $1 $2 $3' _ par1 par2 par3 par4
par2 par3 par4
This does not:
$ bash -c 'shift; printf "%s %s %s\n" $0 $1 $2' par1 par2 par3 par4
par1 par3 par4
This has been defined in POSIX (simplified):
sh -c command_string [command_name [argument...]]
The following additional options shall be supported:
-c
Read commands from the command_string operand. Set the value of special parameter 0 (see Special Parameters) from the value of the command_name operand and the positional parameters ($1, $2, and so on) in sequence from the remaining argument operands.
So, use this:
sh -c 'commands' command_name arg1 arg2 arg3 ....