Sim, o traço parece ser menos útil aqui. Embora não seja culpa, estritamente falando, como não${@%...}
é especificado pelo POSIX :
As quatro variedades a seguir de expansão de parâmetros fornecem processamento de substring. [...] Se o parâmetro for ' #
', ' *
' ou ' @
', o resultado da expansão não é especificado.
É estranho, porém, parece que, se uma expansão como essa modifica o final de um parâmetro posicional, ele descarta os seguintes. Mas não se ele 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 "${@%...}"
processar cada parâmetro posicional de forma independente, o que parece útil.
Suponho que a solução óbvia para isso dash
é fazer a modificação um argumento de cada vez:
for x in "$@"; do echo "${x%%/*}"; done
Pelo que vale, o comportamento das expansões de remoção de prefixo / sufixo usadas $*
também varia entre shells. Bash e ksh parecem modificar os parâmetros primeiro e juntá-los a eles depois, enquanto Zsh e dash juntam os parâmetros primeiro e modificam a sequência concatenada:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
sh
pensa$@
é um único parâmetro para o arquivo inteiro (ou vai quebrar a múltiplos se exceder ARG_MAX) e fazer a expansão no único argumento.Bad substitution
erro nesse código. Pois${*%pattern}
, você vê alguma variação no comportamento em coisas como"$shell" -c 'printf "<%s>\n" "${*%x*}"' sh ax by
ARG_MAX
entra, esse processamento é interno ao shell.