17

As for ./script.sh arg1 [arg2 arg3 ...], the command line arguments arg1, arg2, ... can be got by $1, $2, ... But the number of arguments is NOT fixed.

In the shell script, I want to pass the arguments starting from arg2 to a program,

#/bin/bash
...
/path/to/a/program [I want to pass arg2 arg3 ... to the program]
...

How could I do it since there could be one or more arguments?

Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
wsdzbm
  • 2,786
  • 4
  • 19
  • 27

2 Answers2

19

The usual way would be to save a copy of arg1 ("$1") and shift the parameters by one, so you can refer to the whole list as "$@":

#!/bin/sh
arg1="$1"
shift 1
/path/to/a/program "$@"

bash has some array support of course, but it is not needed for the question as posed.

If even arg1 is optional, you would check for it like this:

if [ $# != 0 ]
then
    arg1="$1"
    shift 1
fi
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
Thomas Dickey
  • 75,040
  • 9
  • 171
  • 268
  • Is the double quotes necessary when using `$@`? – wsdzbm Aug 21 '16 at 23:48
  • 1
    The double-quotes with `$@` tells the shell to double-quote each parameter (something nice to do if the parameters contain interesting characters such as parentheses or asterisks). If you don't care about that, a plain `$*` works... – Thomas Dickey Aug 21 '16 at 23:50
  • 6
    @Lee Yes, the double quotes are necessary. Otherwise, instead of passing through the list of arguments, each argument is split at whitespace, then each piece is interpreted as a wildcard pattern and, if the pattern matches, it's replaced by the list of matches. Generally, speaking, [always double quote variable substitutions](http://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters). – Gilles 'SO- stop being evil' Aug 21 '16 at 23:56
10

You can slice the positional parameters using parameter expansion. The syntax is:

${parameter:offset:length}

If length is omitted it is taken as till the last value.

As you were to pass from second to last arguments, you need:

${@:2}

Example:

$ foo() { echo "${@:2}" ;}

$ foo bar spam egg
spam egg
heemayl
  • 54,820
  • 8
  • 124
  • 141