在参数扩展中可以使用特殊字符,有或没有双引号

时间:2017-03-29 19:32:56

标签: shell posix

在以下所有shell中:

  • 的bash
  • ksh的
  • 的zsh
  • 破折号

并且无法影响shell或shell的选择 设置,我的目标是每当使用默认字符串值(y!) 名为x的变量未设置或为null。即,我想要shell 执行参数扩展生成(y!),其中y代表一些 不涉及任何特殊字符的文字。所以,天真地

${x:-(y!)}

可能有双引号。然后,壳体中的许多差异变得明显 解释这个或变化。在试图 接近可移植性,我尝试了将变量添加到三个\的变体。我也是 尝试过空间的效果,但我现在暂时不做。

${x:-(y!)}, ... , ${x:-\(y\!\)}

我猜,炮弹所显示的其中一个差异与炮弹有关 为历史事件重载!。 (在zsh中尝试!echo。) 当双引号之间出现变体时,其他差异仍然存在。 理想情况下,解决方案可以在双引号之间工作,因为我不能 期望在这种情况下不使用该计划。

例如,给定命令echo "$0: ${x:-\(y\!\)}",即所有(!, 并且)前面有\,shell会回复:

-bash: \(y\!\)
ksh: \(y\!\)
zsh: \(y!\)
dash: \(y\!\)

所以,Z Shell要求不同。事实证明,以下似乎 在bash,ksh,zsh和dash中工作:

$ echo "${x:-$(echo \(y\!\))}"
(y!)

但涉及另一个命令替换(echo,即使 内置(?))似乎有点矫枉过正。有没有更好的办法?什么?我 遗失了什么?

(Zsh似乎使用!{...},而不是\,以“隔离历史记录 相邻字符的引用(如有必要)“(zshexpn(1))。也许这解释了为什么它的反应不同?)

1 个答案:

答案 0 :(得分:1)

使用! char的八进制代码似乎有效:

/bin/echo -e "'${x:-(y\0041)}'"

各种shell的内置echo命令不一致(两个需要-e切换,但dash不理解),因此/bin/echo更多可靠。测试四个炮弹:

unset x
for f in dash bash zsh ksh ; do 
     echo -en "$f:\t"
     $f -c "/bin/echo -e \"'\${x:-(y\0041)}'\""
done

输出:

dash:   '(y!)'
bash:   '(y!)'
zsh:    '(y!)'
ksh:    '(y!)'