领先的美元符号如何影响Bash中的单引号?

use*_*899 54 bash quotes double-quotes single-quotes

我需要将一个字符串传递给程序作为Bash CLI中的参数,例如

program "don't do this"
Run Code Online (Sandbox Code Playgroud)

该字符串可能包含任何字符,如'$','\'等等,我不希望Bash做任何修改.所以我考虑使用单引号.

但是以下不起作用:

 program 'don\'t do this'            //escape doesn't work in single quote
Run Code Online (Sandbox Code Playgroud)

虽然以下两个工作:

 program $'dont\'t do this'          //seems fine, but any other side effects?
 program 'dont'\''do this'           //breaking into 3 parts
Run Code Online (Sandbox Code Playgroud)

第一种方法似乎更好,因为它获得前修改以下(把美元符号在前面,并替换每\\\),但我不知道还有什么美元符号可能会做.

我真的用谷歌搜索了这个,但我找不到我需要的东西......

Ign*_*ams 74

它导致转义序列被解释.

$ echo $'Name\tAge\nBob\t24\nMary\t36'
Name    Age
Bob     24
Mary    36
Run Code Online (Sandbox Code Playgroud)

(并且SO以愚蠢的方式处理标签,所以在家尝试这个)

  • 不,发生这种情况是因为它是“$”...“的定义行为。 (5认同)
  • 那就是$所做的全部。它扩展了POSIX字符串转义符(然后扩展了一些):`\ a` = BEL(贝尔,“警报”),`\ b` = BS(退格),`\ cX` = control + X(例如,\ cG`与`\ a`相同),\ e = ESC(转义),\ f = FF(换页),\ n = LF(换行,换行),\ r = CR (回车),“ \ t” = HT(水平标签),“ \ v” = VT(垂直标签)。 (2认同)
  • 也许聚会迟到了,但是为什么不使用双引号呢? (2认同)
  • @Snusifer 双引号会完成美元符号的 shell 扩展,即 `"foo $(echo pwn > /tmp/pwned)"` 将写入文件 `/tmp/pwned`。简单地替换转义符要付出高昂的代价:-) 但是,这是一种 bashism,因此如果您想继续使用 POSIX /bin/sh,则不可移植。您需要在那里手动执行此操作。 (2认同)

Aar*_*lla 25

使用$作为前缀告诉BASH尝试查找具有该名称的变量.$'是一种特殊的语法(在此完全解释),它支持ANSI-C字符串处理.在这种情况下,单个刻度不是"在下一个刻度之前逐字取值".它应该是非常安全的.缺点是它只是BASH并且非常罕见,所以很多人会想知道这意味着什么.

更好的方法是使用单引号.如果您需要字符串中的单引号,则需要将其替换为'\''.这结束了之前的单引号字符串,向它添加单引号(\')然后启动一个新的单引号字符串.这种语法适用于Bourne shell的任何后代,它很容易理解,并且大多数人很快就能识别出这种模式.

另一种方法是重新替换每个单个tick '"'"',转换为"终止当前单引号字符串,附加双引号字符串,其中只包含一个单一的标记,重新启动单引号字符串".这避免了转义字符,看起来很对称.如果你需要双引号字符串中的双引号,它也可以反过来工作:"'"'".

  • 看到'''''''也很常见.例如''狗''''''尾巴' (2认同)