TL;DR:
bash
l'indicizzazione dell'array inizia da0
(sempre)zsh
l'indicizzazione dell'array inizia da1
(a meno che l'opzioneKSH_ARRAYS
è impostato)
Per ottenere sempre un comportamento coerente, usa:
${array[@]:offset:length}
Spiegazione
Per il codice che funziona sia in bash
e zsh
, devi utilizzare il offset:length
sintassi anziché [subscript]
sintassi.
Anche per zsh
-only code, dovrai comunque farlo (o utilizzare emulate -LR zsh
) da zsh
la base di indicizzazione dell'array di è determinata da KSH_ARRAYS
opzione.
Ad esempio, per fare riferimento al primo elemento in un array:
${array[@]:0:1}
Qui, array[@]
sono tutti gli elementi, 0
è l'offset (che sempre è in base 0) e 1
è il numero di elementi desiderati.
Gli array in Bash sono indicizzati da zero e in zsh sono indicizzati da uno.
Ma non hai bisogno degli indici per un semplice caso d'uso come questo. Loop su ${array[@]}
funziona in entrambi:
files=(file*)
for f in "${files[@]}"; do
echo "$f"
done
In zsh puoi anche usare $files
invece di "${files[@]}"
, ma non funziona in Bash. (E c'è la leggera differenza che elimina gli elementi dell'array vuoti, ma non ne otterrai alcuno dai nomi dei file.)
Inoltre, non utilizzare $(ls file*)
, si romperà se hai nomi di file con spazi (vedi WordSpliting su BashGuide), ed è completamente inutile per cominciare.
La shell è perfettamente in grado di generare nomi di file da sola. Questo è effettivamente ciò che accadrà lì, la shell trova tutti i file con nomi corrispondenti a file*
, li passa a ls
e ls
semplicemente li stampa di nuovo affinché la shell li legga e li elabori.