在Bash中,如何在单引号字符串中转义单引号?

90

我想在Bash中以如下方式显示字符串

I'm a student
当然你可以像这样做。
echo "I'm a student"

但是在使用单引号包围字符串的情况下如何实现此操作?


4
抱歉,无法在单引号之间插入单引号。请参阅 http://www.gnu.org/software/bash/manual/bashref.html#Special-Parameters 中的第 3.1.2.2 节“单引号”。 - 爱国者
那么在脚本中,你该如何操作?su -c '/etc/init.d/myservice start' -l myuser(以root用户身份运行) - Sandburg
可能的规范是*如何在单引号字符串中转义单引号*(2009年,26个回答,1380个赞)。一个答案涵盖了这里的顶级答案的内容。 - Peter Mortensen
5个回答

161
echo 'I\'m a student'

不起作用。但是以下的方法有效:
echo $'I\'m a student'

从Bash的man页面中:
引用: 单引号不能出现在单引号之间,即使在反斜杠之前也不行。 .... 以$'string'形式的单词被特殊处理。该单词扩展为字符串,其中的反斜杠转义字符按照ANSI C标准指定的方式替换。

5
更加通俗易懂的表达方式是:“我是一名学生。”较为丑陋的写法为:“'I'"'"'m a student'”。 - glenn jackman
4
echo $'I\'m a student!' => !': 事件未找到,这不是一个真正的单引号字符串,在bash中应该保护免受任何解释。 - regilero
1
@regilero 这个问题出现在哪些版本中?我在bash 4.1.2中没有看到这个错误。 - sappjw
根据手册,@regilero说:“扩展结果是单引号括起来的,就好像美元符号不存在一样。” https://www.gnu.org/savannah-checkouts/gnu/bash/manual/bash.html#ANSI_002dC-Quoting - CervEd
以防万一,截至2023年,dashash(即/bin/sh的常见别名)不支持$'或Bash的ANSI-C引用,因为我相信它不符合POSIX标准。 - undefined
显示剩余3条评论

77
“丑陋”的解决方案格伦·杰克曼提到的实际上应该被列为顶级答案。它在某些情况下运作良好,实际上非常优雅。
'I'"'"'m a student'

这个单引号字符串在 I 后结束,然后立即开始一个包含单引号的双引号字符串,然后又开始了另一个单引号字符串。Bash 将所有连续的字符串连接成一个字符串。
太棒了!

53
我认为我们对美的定义有些不同.. ;) - Håvard Geithus
3
严格来说,它并没有回答如何在单引号字符串内部转义单引号的问题。;-) - Roland Weber
最常见的问题是想要在重构代码时进入“n级”。这并不能满足这种需求。虽然 $ 不一定具有“+n”的能力。我不确定,我需要进行更多的测试。但是对我来说,看起来像是我将能够执行已经存储在单引号中的代码,并将其存储到单独的变量中。 - tatsu
为什么不直接使用 echo I"'"m a student - wk_j

36
下面的例子有效是因为转义的单引号 \' 在技术上处于两个单引号参数之间。
echo 'I'\''m a student'

1
这似乎是最好的答案。我猜它没有得到高票,因为它是在之前的答案发布几年后发布的。 - secluded
比上面的回答好得多,且远不那么令人困惑! - Michael Goldshteyn
在scp命令中出现错误,提示未找到匹配的''。 - Michael Rogers

0

另一种解决方法是使用printf而不是echo,并使用\x27转义所需的单引号:

printf 'I\x27m a student!\n'

-4

我建议

echo "我是一名学生"

就像其他编程语言一样。


5
这个问题难道不是排除了这种方法吗?当然你可以用这种方法:echo "我是学生",但如果要使用单引号将字符串括起来,该怎么实现呢? - Jeff Schaller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接