Đúng, dấu gạch ngang dường như ít hữu ích hơn ở đây. Mặc dù nó không có lỗi, nói đúng, như ${@%...}
là không xác định bởi POSIX :
Bốn giống mở rộng tham số sau đây cung cấp cho xử lý chuỗi con. [...] Nếu tham số là ' #
', ' *
' hoặc ' @
', kết quả của việc mở rộng là không xác định.
Mặc dù điều này thật kỳ lạ, có vẻ như nếu một bản mở rộng như thế sửa đổi phần cuối của một tham số vị trí, thì nó sẽ loại bỏ các tham số sau. Nhưng không, nếu nó không thực sự sửa đổi kết thúc:
$ 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 và Zsh dường như đều xử lý "${@#...}"
và "${@%...}"
bằng cách xử lý từng tham số vị trí một cách độc lập, điều này dường như là điều hữu ích để làm.
Tôi cho rằng cách giải quyết rõ ràng dash
là thực hiện sửa đổi một đối số tại một thời điểm:
for x in "$@"; do echo "${x%%/*}"; done
Đối với giá trị của nó, hành vi của các mở rộng loại bỏ tiền tố / hậu tố được sử dụng $*
cũng khác nhau giữa các shell. Bash và ksh dường như sửa đổi các tham số trước và tham gia chúng sau đó, trong khi Zsh và dash tham gia các tham số trước và sửa đổi chuỗi nối:
$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
sh
nghĩ$@
là một tham số duy nhất cho toàn bộ tệp (hoặc sẽ phá vỡ thành nhiều nếu vượt quá ARG_MAX) và thực hiện mở rộng trên đối số duy nhất.