Ja, Bindestrich scheint hier weniger als nützlich zu sein. Obwohl es nicht Schuld ist, streng genommen, wie ${@%...}
ist nicht spezifiziert durch POSIX :
Die folgenden vier Varianten der Parametererweiterung ermöglichen die Verarbeitung von Teilzeichenfolgen. [...] Wenn der Parameter ' #
', ' *
' oder ' @
' ist, ist das Ergebnis der Erweiterung nicht angegeben.
Es ist jedoch seltsam, es scheint, dass wenn eine solche Erweiterung das Ende eines Positionsparameters ändert, die folgenden gelöscht werden. Aber nicht, wenn es das Ende nicht wirklich verändert:
$ dash -c 'set -- foo bar; printf "<%s>\n" "${@%o}";'
<fo>
$ dash -c 'set -- foo bar; printf "<%s>\n" "${@%x}";'
<foo>
<bar>
$ dash -c 'set -- foo bar doo; printf "<%s>\n" "${@%r}";'
<foo>
<ba>
Bash, ksh und Zsh scheinen alle Positionsparameter unabhängig zu handhaben "${@#...}"
und zu "${@%...}"
verarbeiten, was als nützlich erscheint.
Ich nehme an, die offensichtliche Problemumgehung dash
besteht darin, die Änderung Argument für Argument zu machen:
for x in "$@"; do echo "${x%%/*}"; done
Für das, was es wert ist, $*
variiert das Verhalten der Erweiterungen zum Entfernen von Präfixen / Suffixen auch zwischen Shells. Bash und ksh scheinen zuerst die Parameter zu ändern und sie danach zu verbinden, während Zsh und dash zuerst die Parameter verbinden und die verkettete Zeichenfolge ändern:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
sh
denkt, dass dies$@
ein einzelner Parameter für die gesamte Datei ist (oder bei Überschreitung von ARG_MAX in mehrere Parameter zerfällt) und das einzige Argument erweitert.Bad substitution
Fehler in diesem Code geben. Denn${*%pattern}
Sie sehen einige Variationen im Verhalten in Dingen wie"$shell" -c 'printf "<%s>\n" "${*%x*}"' sh ax by
ARG_MAX
, dass die Verarbeitung innerhalb der Shell erfolgt.