TL;DR:
bashDie Array-Indizierung beginnt bei0(immer)zshDie Array-Indizierung beginnt bei1(außer OptionKSH_ARRAYSeingestellt 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.