I see this in a shell script.
variable=${@:2}
What is it doing?
It's showing the contents of the special variable $@
, in Bash. It contains all the command line arguments, and this command is taking all the arguments from the second one on and storing them in a variable, variable
.
Here's an exampe script.
#!/bin/bash
echo ${@:2}
variable=${@:3}
echo $variable
Example run:
./ex.bash 1 2 3 4 5
2 3 4 5
3 4 5
vars=( "${@:2}" )
Commented
Sep 30, 2013 at 13:11
$@
and ${@}
are identical, although the latter is the "more correct" syntax. You have to use the brackets with ${@:2}
, because $@:2
is ambiguous and would therefore be interpreted as ${@}:2
, which is not the same thing.
Commented
Sep 30, 2013 at 18:33
That's a ksh
feature also found in bash
and recent versions of zsh
.
In ksh
and bash
, you can access several elements of an array by using the ${array[@]:first:length}
syntax, which expands to up to length
(or all if length
is omitted) elements of the array
array (in the list of elements of the array sorted numerically on the indexes), starting with the first one with index greater or equal to first
. When in scalar context (like here in an assignment to a scalar variable) the list of elements is joined with space characters with bash
and ksh93
and with the first character of $IFS
(or nothing if $IFS
is empty or space if it is unset) with zsh
.
For instance:
$ a[23]=a a[5]=b a[235]=c a[45]=d
$ x=${a[@]:12:2}; printf '<%s>\n' "$x"
<a d>
$@
is a special case. $@
is the array of positional parameters ($1
, $2
...). But when used with :
, $0
is also included. So ${@:1}
is the same as $@
, not ${@:0}
like for other arrays.
In zsh
, it's slightly different. zsh
added the ksh
syntax only recently for compatibility but has its own syntax for selecting ranges of elements.
Contrary to ksh
and bash
, zsh
arrays are a different variable type from scalar variables, are not sparse (zsh
has associative arrays as another variable type) and start at index 1 instead of 0.
For zsh
, you access array element ranges with $a[first,last]
(where last
can also be negative to count backwards from the end).
In zsh
,
a[23]=a a[5]=b a[235]=c a[45]=d
creates an array with 235 elements, most of them empty. $a[12,50]
would expand to elements 12 to 50, and ${a[@]:12:2}
would only expand to the (empty) $a[12]
and $a[13]
elements. As a special case, and again for portability with ksh93
and bash
, zsh
also accepts a 0
first element for $@
and treats that as $0
.
So, you can use ${a[@]:x:n}
and ${@:x:n}
portably across all 3 shells, but only for non-sparse arrays, and pay attention to the value of IFS.
var="my_value"; echo var="${var[@]:2}"; echo "$var"
See the difference?