Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use positional parameters with "bash -c" command?

Tags:

bash

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 that:

If there are arguments after the command_string, they are assigned to the positional parameters, starting with $0.

So I guess that the following form is the right one:

$ bash -c 'printf "%s %s %s\n" $0 $1 $2' param1 param2 param3
param1 param2 param3

However I saw the following form, and I wonder why it would be better

$ bash -c 'printf "%s %s %s\n" $1 $2' _ param1 param2
param1 param2 

In this case, the character _ replaces $0.

I know that for many interpreters $0 has a special meaning (command name, all positional parameters...), but in this case the man pages are quite clear.

So, is there something wrong with the first form and is there any drawback of using $0 as the first positional parameter for the bash -c command?

like image 255
oliv Avatar asked Aug 10 '16 07:08

oliv


1 Answers

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.

The shell treats $0 differently

One 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 name

In 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.

like image 87
John1024 Avatar answered Oct 05 '22 12:10

John1024