Sì, il trattino sembra essere poco utile qui. Anche se non è esente da colpa, a rigor di termini, come ${@%...}è specificato da POSIX :
Le seguenti quattro varietà di espansione dei parametri prevedono l'elaborazione della sottostringa. [...] Se il parametro è ' #', ' *' o ' @', il risultato dell'espansione non è specificato.
È strano però, se un'espansione del genere modifica la fine di un parametro posizionale, rilascia i seguenti. Ma non se in realtà non modifica la fine:
$ 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 e Zsh sembrano tutti in grado di gestire "${@#...}"ed "${@%...}"elaborare ogni parametro posizionale in modo indipendente, il che sembrerebbe la cosa utile da fare.
Suppongo che l'evidente soluzione alternativa dashsia quella di rendere la modifica un argomento alla volta:
for x in "$@"; do echo "${x%%/*}"; done
Per quello che vale, il comportamento delle espansioni di rimozione prefisso / suffisso utilizzate $*varia anche tra le shell. Bash e ksh sembrano modificare prima i parametri e unirli successivamente, mentre Zsh e dash uniscono prima i parametri e modificano la stringa concatenata:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
shpensa che$@sia un singolo parametro per l'intero file (o si spezzerà in più se supera ARG_MAX) e farà l'espansione sull'unico argomento.