TL;DR:
bash
Die Array-Indizierung beginnt bei0
(immer)zsh
Die Array-Indizierung beginnt bei1
(außer OptionKSH_ARRAYS
eingestellt ist)
Um immer konsistentes Verhalten zu erhalten, verwenden Sie:
${array[@]:offset:length}
Erklärung
Für Code, der in beiden bash
funktioniert und zsh
, müssen Sie den offset:length
verwenden Syntax anstelle von [subscript]
Syntax.
Sogar für zsh
-only Code, müssen Sie dies trotzdem tun (oder verwenden Sie emulate -LR zsh
) seit zsh
Die Array-Subskriptionsbasis von wird durch KSH_ARRAYS
bestimmt Option.
ZB um das erste Element in einem Array zu referenzieren:
${array[@]:0:1}
Hier, array[@]
sind alle Elemente, 0
ist der Offset (der immer ist 0-basiert) und 1
ist die Anzahl der gewünschten Elemente.
Arrays in Bash werden von Null aus indiziert, und in Zsh werden sie von Eins aus indiziert.
Für einen einfachen Anwendungsfall wie diesen benötigen Sie die Indizes jedoch nicht. Schleife über ${array[@]}
funktioniert in beiden:
files=(file*)
for f in "${files[@]}"; do
echo "$f"
done
In zsh könnten Sie auch $files
verwenden statt "${files[@]}"
, aber das funktioniert nicht in Bash. (Und es gibt den kleinen Unterschied, dass es leere Array-Elemente löscht, aber Sie erhalten keine von Dateinamen.)
Verwenden Sie außerdem nicht $(ls file*)
, wird es brechen, wenn Sie Dateinamen mit Leerzeichen haben (siehe WordSpliting auf BashGuide), und ist zunächst völlig nutzlos.
Die Shell ist durchaus in der Lage, Dateinamen selbst zu generieren. Genau das passiert dort, die Shell findet alle Dateien mit Namen, die file*
entsprechen , übergibt sie an ls
, und ls
druckt sie einfach erneut aus, damit die Shell sie lesen und verarbeiten kann.