First, note that $@ without quotes makes no sense and should not be used. $@ should only be used quoted ("$@") and in list contexts.
for i in "$@" qualifies as a list context, but here, to loop over the positional parameters, the canonical, most portable and simpler form is:
for i
do something with "$i"
done
Now, to loop over the elements starting from the second one, the canonical and most portable way is to use shift:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
After shift, what used to be $1 has been removed from the list (but we've saved it in $first_arg) and what used to be in $2 is now in $1. The positional parameters have been shifted 1 position to the left (use shift 2 to shift by 2...). So basically, our loop is looping from what used to be the second argument to the last.
With bash (and zsh and ksh93, but that's it), an alternative is to do:
for i in "${@:2}"
do something with "$i"
done
But note that it's not standard sh syntax so should not be used in a script that starts with #! /bin/sh -.
In zsh or yash, you can also do:
for i in "${@[3,-3]}"
do something with "$i"
done
to loop from the 3rd to the 3rd last argument.
In zsh, $@ is also known as the $argv array. So to pop elements from the beginning or end of the arrays, you can also do:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
(shift can also be written 1=() in zsh)
In bash, you can only assign to the $@ elements with the set builtin, so to pop 3 elements off the end, that would be something like:
set -- "${@:1:$#-3}"
And to loop from the 3rd to the 3rd last:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, to pop the last 3 elements of "$@", you'd need to use a loop:
n=$(($# - 3))
for arg do
[ "$n" -gt 0 ] && set -- "$@" "$arg"
shift
n=$((n - 1))
done
for ((i=2; i<=$#; i++)); do something with "${!i}"; done– glenn jackman Aug 27 '15 at 20:24$@without quotes makes no sense and should not be used? – Martin Vegter Jul 25 '21 at 05:29"$@"means quote every string in$*, so forcmd "a = b" c d, insidecmd,"$@"would have three elements,a = b,b, andc, whereas$@would be no different than$*, producing 5 elements:a,=,b,c, andd. – Jeff Learman Jan 28 '22 at 16:56