How do I use $* while omitting certain input variables like $1 and $2 in bash script?

Solution 1:

You can use bash Parameter Expansion to specify a range, this works with positional parameters as well. For $3$n it would be:

"${@:3}" # expands to "$3" "$4" "$5" …
"${*:3}" # expands to "$3 $4 $5 …"

Be aware that both $@ and $* ignore the first argument $0. If you wonder which one to use in your case: it’s very probable that you want a quoted $@. Don’t use $* unless you explicitly don’t want the arguments to be quoted individually.

You can try it out as follows:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6
3 4 5 6
$ echo 'echo "${@:3}"' >script_file
$ bash script_file 0 1 2 3 4 5 6
2 3 4 5 6

Note that in the first example $0 is filled with the first argument 0 while when used in a script $0 is instead filled with the script’s name, as the second example shows. The script’s name to bash of course is the first argument, just that it's normally not perceived as such – the same goes for a script made executable and called “directly”. So in the first example we have $0=0, $1=1 etc. while in the second it’s $0=script_file, $1=0, $2=1 etc.; ${@:3} selects every argument starting with $3.

Some additional examples for possible ranges:

 # two arguments starting with the third
$ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6
3 4
 # every argument starting with the second to last one
 # a negative value needs either a preceding space or parentheses
$ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6
5 6
 # two arguments starting with the fifth to last one
$ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6
2 3

Further reading:

  • man bash/EXPANSION/Parameter Expansion
  • bash-hackers.org: Handling positional parameters
  • TLDP Advanced Bash-Scripting Guide: Parameter Substitution

Solution 2:

You can use the shift builtin:

$ help shift
shift: shift [n]
    Shift positional parameters.

    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.

    Exit Status:
    Returns success unless N is negative or greater than $#.

Ex. given

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

then

$ ./argtest.bash foo bar baz bam boo
baz bam boo