Innanzitutto, nota che $@
senza virgolette non ha senso e non dovrebbe essere usato. $@
dovrebbe essere usato solo tra virgolette ( "$@"
) e in contesti di lista.
for i in "$@"
si qualifica come un contesto di elenco, ma qui, per passare in rassegna i parametri posizionali, la forma canonica, più portatile e più semplice è:
for i
do something with "$i"
done
Ora, per passare in rassegna gli elementi a partire dal secondo, il modo canonico e più portatile è usare shift
:
first_arg=$1
shift # short for shift 1
for i
do something with "$i"
done
Dopo shift
, ciò che era $1
stato rimosso è stato rimosso dall'elenco (ma lo abbiamo salvato in $first_arg
) e quello che era in $2
è ora $1
. I parametri posizionali sono stati spostati 1
verso sinistra (usare shift 2
per spostare di 2 ...). Quindi, in sostanza, il nostro ciclo sta passando da quello che era il secondo argomento all'ultimo.
Con bash
(e zsh
e ksh93
, ma questo è tutto), un'alternativa è fare:
for i in "${@:2}"
do something with "$i"
done
Ma nota che non è una sh
sintassi standard, quindi non dovrebbe essere usata in uno script che inizia con #! /bin/sh -
.
In zsh
o yash
, puoi anche fare:
for i in "${@[3,-3]}"
do something with "$i"
done
per passare dal 3o al 3o ultimo argomento.
In zsh
, $@
è anche noto come $argv
array. Quindi, per far apparire gli elementi dall'inizio o dalla fine delle matrici, puoi anche fare:
argv[1,3]=() # remove the first 3 elements
argv[-3,-1]=()
( shift
può anche essere scritto 1=()
in zsh
)
In bash
, puoi solo assegnare agli $@
elementi con l' set
integrato, quindi per estrarre 3 elementi alla fine, sarebbe qualcosa del tipo:
set -- "${@:1:$#-3}"
E per passare dal 3 ° al 3 ° ultimo:
for i in "${@:3:$#-5}"
do something with "$i"
done
POSIX, per far apparire gli ultimi 3 elementi di "$@"
, avresti bisogno di usare un 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