sh shell 不支持 $@ 上的参数扩展吗?

αғs*_*нιη 8 shell bash dash

我在 AU 上发布一个问题的答案,我发现参数扩展 on$@不适用于shshell:

<infile xargs -d'\n' sh -c 'echo "${@%%/*}"' _
Run Code Online (Sandbox Code Playgroud)

但它在bash. 这是shshell 的预期行为,我如何在那里执行扩展?

此外,我知道通过-n1选项xargs我一次只能将一行传递给命令,但我对是否sh可以扩展感兴趣$@

<infile xargs -d'\n' -n1 sh -c 'echo "${0%%/*}"'
Run Code Online (Sandbox Code Playgroud)

infile 包含:

A1 /B1/C1
A 2/B2/C2
A3/B3/C3
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 12

是的,破折号在这里似乎不太有用。虽然它是没有过错的,严格来说,作为${@%...}不确定的POSIX

以下四种参数扩展提供了子串处理。[...] 如果参数是“ #”、“ *”或“ @”,则扩展的结果未指定。

不过这很奇怪,似乎如果这样的扩展修改了一个位置参数的末尾,它会删除以下参数。但如果它实际上没有修改结尾,则不会:

$ 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>
Run Code Online (Sandbox Code Playgroud)

Bash、ksh 和 Zsh 似乎都独立处理"${@#...}""${@%...}"通过处理每个位置参数,这似乎是有用的事情。

我想明显的解决方法dash是一次修改一个参数:

for x in "$@"; do echo "${x%%/*}"; done
Run Code Online (Sandbox Code Playgroud)

就其价值而言,使用的前缀/后缀删除扩展的行为$*也因壳而异。bash 和 ksh 似乎是先修改参数,然后再加入,而 Zsh 和 dash 则是先加入参数,然后修改连接后的字符串:

$ zsh -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a>
$ bash -c 'set -- ax bx; printf "<%s>\n" "${*%%x*}";'
<a b>
Run Code Online (Sandbox Code Playgroud)