Yap, tanda hubung tampaknya kurang berguna di sini. Meskipun itu tidak salah, sebenarnya, seperti ${@%...}
yang tidak ditentukan oleh POSIX :
Empat varietas berikut ekspansi parameter menyediakan untuk pemrosesan substring. [...] Jika parameternya adalah ' #
', ' *
', atau ' @
', hasil ekspansi tidak ditentukan.
Anehnya, tampaknya jika ekspansi seperti itu mengubah akhir dari satu parameter posisi, ia menjatuhkan yang berikut ini. Tetapi tidak jika itu tidak benar-benar mengubah akhirnya:
$ 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 dan Zsh semuanya tampaknya menangani "${@#...}"
dan "${@%...}"
dengan memproses setiap parameter posisi secara independen, yang tampaknya berguna untuk dilakukan.
Saya kira solusi nyata untuk dash
membuat modifikasi satu argumen pada satu waktu:
for x in "$@"; do echo "${x%%/*}"; done
Untuk apa nilainya, perilaku ekspansi penghapusan awalan / akhiran yang digunakan $*
juga bervariasi antara shell. Bash dan ksh tampaknya memodifikasi parameter terlebih dahulu dan bergabung dengan mereka setelah itu, sementara Zsh dan dash bergabung dengan parameter terlebih dahulu dan memodifikasi string yang digabungkan:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
sh
berpikir$@
adalah parameter tunggal untuk seluruh file (atau akan pecah menjadi beberapa jika melebihi ARG_MAX) dan melakukan ekspansi pada satu-satunya argumen.Bad substitution
kesalahan pada kode itu. Sebab${*%pattern}
, Anda melihat beberapa variasi dalam perilaku dalam hal-hal seperti"$shell" -c 'printf "<%s>\n" "${*%x*}"' sh ax by
ARG_MAX
masuk ke dalamnya, pemrosesan itu internal ke shell.