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:
shift
approach will make it impossible to access$1
and$2
after you shifted them. In your script you use$2
alongside the$variable_in_question
, you either need to change that or use the Parameter Expansion approach. – dessert Mar 03 '18 at 23:19shift
is good when the first one or more args are special and it makes sense to pick them out into separate variables (foo="$1"; bar="$2";
, orif [[ something with $1 ]];then blah blah; shift
. But @dessert's answer with the non-destructive approach is nice in other cases when you do still want the full list later, or when you use fancier syntax to pick out a limited range of args, not out to infinity, without introducing empty args to a command if$@
doesn't have that many elements. – Peter Cordes Mar 04 '18 at 02:00