What does this ${@:2} mean in shell scripting
Solution 1
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
.
Example
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
References
Solution 2
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.
Related videos on Youtube
Lenin Raj Rajasekaran
Updated on September 18, 2022Comments
-
Lenin Raj Rajasekaran almost 2 years
I see this in a shell script.
variable=${@:2}
What is it doing?
-
Admin over 10 yearsIs that exactly how it showed in the script? The syntax looks like an array but is missing some pieces. Can you please post a couple of the lines around this line from the script?
-
Admin over 10 yearsThat is a variable starting from the second letter.
var="my_value"; echo var="${var[@]:2}"; echo "$var"
See the difference?
-
-
Angel Todorov over 10 yearsNote that the technique shown mashes the given arguments into a single string. If you need to keep them as separate arguments, use an array:
vars=( "${@:2}" )
-
Paddy Landau over 10 yearsAlso note the use of the curly brackets. You are supposed to always use curly brackets, but Bash allows you to omit them when the context is unambiguous. Therefore,
$@
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. -
information_interchange about 4 yearsThanks for explaining the array indexing syntax