Inside my bash script, I would like to parse zero, one or two parameters (the script can recognize them), then forward the remaining parameters to a command invoked in the script. How can I do that?
3 Answers
Use the shift built-in command to "eat" the arguments. Then call the child process and pass it the "$@" argument to include all remaining arguments. Notice the quotes, they should be kept, since they cause the expansion of the argument list to be properly quoted.
9 Comments
pixelbeat
actually "$@" is safer than $*
Cascabel
$@ essentially treats each element of the array as a quoted string - they are passed along without opportunity for expansion. It also ensures that each is seen as a separate word. This explanation along with a test script demonstrating the difference is here: tldp.org/LDP/abs/html/internalvariables.html#APPREFCadoiz
Pay attention to use quotes! Read more on why it is important them around here: stackoverflow.com/a/4824637/4575793
axolotl
to clarify a quesiton I had before trying this solution:
"$@" does not pass the script/command name itself as a parameter, unlike sys.argv[0] in C-family language. In other words, you're good to simply call whatever command it was as cmd_inside_script "$@"ben-albrecht
Too many pending edits to add myself, but this answer would be improved with a simple code snippet example. It's unclear if
shift requires arguments without looking at the docs or reading other answers with examples. |
Bash supports subsetting parameters (see Subsets and substrings), so you can choose which parameters to process/pass like this.
open new file and edit it: vim
r.sh:echo "params only 2 : ${@:2:1}" echo "params 2 and 3 : ${@:2:2}" echo "params all from 2: ${@:2:99}" echo "params all from 2: ${@:2}"run it:
$ chmod u+x r.sh $ ./r.sh 1 2 3 4 5 6 7 8 9 10the result is:
params only 2 : 2 params 2 and 3 : 2 3 params all from 2: 2 3 4 5 6 7 8 9 10 params all from 2: 2 3 4 5 6 7 8 9 10
Comments
bash uses the shift command:
e.g. shifttest.sh:
#!/bin/bash
echo $1
shift
echo $1 $2
shifttest.sh 1 2 3 produces
1
2 3
5 Comments
Kyle Chadha
@TamásZahola care to explain?
Tamás Zahola
If you forward the arguments as
$1 without quoting them as "$1", then the shell will perform word splitting, so e.g. foo bar will be forwarded as foo and bar separately.Cadoiz
Read more on why it is important to have the double " around here: stackoverflow.com/a/4824637/4575793
Alex
My brain jumbled up a couple of letters in "shifttest" and I consequently read it as something else.
Daniel Kaplan
Doesn't this only answer half the question? How do you forward the remaining parameters? Rhetorical question: the accepted answer explains you use
forward-to-me.sh "$@"