前面的美元符号如何影响 Bash 中的单引号?

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

program "don't do this"

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

然而,以下方法不起作用:

 program 'don\'t do this'            //escape doesn't work in single quote

而以下两个作品:

 program $'dont\'t do this'          //seems fine, but any other side effects?
program 'dont'\''do this'           //breaking into 3 parts

第一种方法似乎更好,因为它获得较少的预修改(将美元符号放在前面,并将每个 \替换为 \\) ,但我不知道美元符号还可以做什么。

我真的谷歌了这个,但我找不到我需要的..。

26649 次浏览

It causes escape sequences to be interpreted.

$ echo $'Name\tAge\nBob\t24\nMary\t36'
Name    Age
Bob     24
Mary    36

After those sequences are expanded, the result is single-quoted, as if the dollar sign had not been present.

Using $ as a prefix tells BASH to try to find a variable with that name. $' is a special syntax (fully explained here) which enables ANSI-C string processing. In this case, the single tick isn't "take value verbatim until the next single tick". It should be quite safe to use. The drawbacks are it's BASH only and quite uncommon, so many people will wonder what it means.

The better way is to use single quotes. If you need a single quote in a string, you need to replace it with '\''. This ends the previous single quoted string, adds a single quote to it (\') and then starts a new single quoted string. This syntax works with any descendant of the Bourne shell, it's pretty easy to understand and most people quickly recognize the pattern.

The alternative is to replase each single tick with '"'"' which translates to "terminate current single quoted string, append double quoted string which contains just a single tick, restart single quoted string". This avoid the escape character and looks nicely symmetric. It also works the other way around if you need a double quote in a double quoted string: "'"'".

You won't find a faster or more efficient way than:

eval RESULT=\$\'$STRING\'

For one, this is the kind of thing that eval is there for, and you avoid the crazy cost of forking subprocess all over the place, as the previous answers seem to suggest. Your example:

$ foo='\u25b6'
$ eval bar=\$\'$foo\'
$ echo "$bar"
▶