Sim, o traço parece ser menos que útil aqui. Embora não seja a culpa, estritamente falando, como ${@%...}
é não especificado por POSIX :
The following four varieties of parameter expansion provide for substring processing. [...] If parameter is '
#
', '*
', or '@
', the result of the expansion is unspecified.
É estranho, parece que, se uma expansão como essa modifica o fim de um parâmetro posicional, ela elimina as seguintes. Mas não se realmente não modificar o final:
$ 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 parecem manipular "${@#...}"
e "${@%...}"
processando cada parâmetro posicional independentemente, o que parece ser útil.
Suponho que a solução óbvia para dash
é tornar a modificação um argumento por vez:
for x in "$@"; do echo "${x%%/*}"; done
Por que vale a pena, o comportamento das expansões de remoção de prefixo / sufixo usadas em $*
também varia entre os shells. Bash e ksh parecem modificar os parâmetros primeiro e juntá-los depois disso, enquanto Zsh e dash juntam os parâmetros primeiro e modificam a string concatenada:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>