По-перше, зауважте, що $@без лапок немає сенсу і не слід їх використовувати. $@слід використовувати лише цитуючи ( "$@") та в контексті списку.
for i in "$@" кваліфікується як контекст списку, але тут, для переходу на позиційні параметри, канонічною, найбільш портативною та простішою формою є:
for i
do something with "$i"
done
Тепер, щоб провести цикл на елементи, починаючи з другого, використовується канонічний і найбільш портативний спосіб shift:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Після цього shiftте, що раніше $1було видалено зі списку (але ми зберегли його в $first_arg), і те, що раніше було $2в ньому $1. Позиційні параметри зміщені 1 вліво (використовуйте shift 2для зміщення на 2 ...). Отже, наша петля переходить від того, що було другим аргументом до останнього.
З bash(і zshта ksh93, але це так), альтернатива зробити:
for i in "${@:2}"
do something with "$i"
done
Але зауважте, що це не стандартний shсинтаксис, тому його не слід використовувати в сценарії, який починається з #! /bin/sh -.
У zshабо yashви також можете зробити:
for i in "${@[3,-3]}"
do something with "$i"
done
перевести цикл від 3-го до 3-го останнього аргументу.
В zsh, $@також відомий як $argvмасив. Отже, щоб виводити елементи з початку чи кінця масивів, ви також можете зробити:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shiftТакож може бути записана 1=()в zsh)
У програмі bashви можете призначити лише $@елементи за допомогою setвбудованого, щоб вивести 3 елементи з кінця, це було б щось на зразок:
set -- "${@:1:$#-3}"
І перевести цикл від 3-го до 3-го останнього:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIXly, щоб вивести останні 3 елементи "$@", вам потрібно використовувати цикл:
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