По-перше, зауважте, що $@
без лапок немає сенсу і не слід їх використовувати. $@
слід використовувати лише цитуючи ( "$@"
) та в контексті списку.
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