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.
-
34
-
1@pixelbeat: Thanks, good catch. I edited. @Łukasz Lew: see the linked-to page in the manual. :) Basically, it handles quoting better.– unwindCommented Oct 8, 2009 at 13:18
-
28
$@
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#APPREF– CascabelCommented Oct 8, 2009 at 14:43 -
3Pay attention to use quotes! Read more on why it is important them around here: stackoverflow.com/a/4824637/4575793– CadoizCommented Jul 13, 2019 at 15:59
-
3to clarify a quesiton I had before trying this solution:
"$@"
does not pass the script/command name itself as a parameter, unlikesys.argv[0]
in C-family language. In other words, you're good to simply call whatever command it was ascmd_inside_script "$@"
– axolotlCommented Feb 3, 2022 at 21:39
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 10
the 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
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
-
2
-
4If 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 asfoo
andbar
separately. Commented Jul 17, 2018 at 17:54 -
Read more on why it is important to have the double " around here: stackoverflow.com/a/4824637/4575793– CadoizCommented Jul 13, 2019 at 16:00
-
4My brain jumbled up a couple of letters in "shifttest" and I consequently read it as something else.– AlexCommented May 23, 2020 at 17:34
-
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 "$@"
Commented Jan 16 at 23:16