如何在shell中转义报价?


65

我在转义bash字符时遇到麻烦。我想在其他用户下运行命令时转义单引号和双引号。出于这个问题的目的,假设我想在屏幕上回显以下内容:

'single quote phrase' "double quote phrase"

如果还需要切换到其他用户,该如何转义所有特殊字符:

sudo su USER -c "echo \"'single quote phrase' \"double quote phrase\"\""

当然,这不会产生正确的结果。


+1表示“当然,这不会产生正确的结果”。bash快要让我生气了。
罗尔夫(Rolf)'18

Answers:


88

您可以使用以下字符串文字语法:

> echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

man bash

$'string'形式的单词经过特殊处理。该单词扩展为字符串,并按ANSI C标准的规定替换反斜杠转义字符。反斜杠转义序列(如果存在)的解码方式如下:

          \a     alert (bell)
          \b     backspace
          \e
          \E     an escape character
          \f     form feed
          \n     new line
          \r     carriage return
          \t     horizontal tab
          \v     vertical tab
          \\     backslash
          \'     single quote
          \"     double quote
          \nnn   the eight-bit character whose value is the octal value nnn (one to three digits)
          \xHH   the eight-bit character whose value is the hexadecimal value HH (one or two hex digits)
          \cx    a control-x character

5
过度杀伤力。在大多数情况下,您不需要使用字符串文字语法。
fpmurphy'2

此处有更多详细信息stackoverflow.com/a/16605140/149221
mj41 '18年

12

在POSIX Shell中,假设您的字符串中没有变量,命令或历史记录扩展,并且没有换行符,请遵循以下基本规定:

  1. 要用单引号引起来的通用字符串,请执行以下操作:

    1. 用相同的序列替换任何非单引号字符序列,并添加前导和尾随单引号: 'aaa' ==> ''aaa''

    2. 每个先前存在的单引号字符都使用反斜杠转义:' ==> \'
      特别是,''aaa'' ==> \''aaa'\'

  2. 要用双引号引起来的通用字符串,请执行以下操作:

    1. 添加前导和尾随双引号: aaa ==> "aaa"

    2. 每个双引号字符和每个反斜杠字符都使用反斜杠转义: " ==> \", \ ==> \\

几个例子:

''aaa""bbb''ccc\\ddd''  ==>  \'\''aaa""bbb'\'\''ccc\\ddd'\'\'
                        ==>  "''aaa\"\"bbb''ccc\\\\ddd''"

这样您的示例可以通过以下内容进行扩展:

#!/bin/sh

echo \''aaa'\'' "bbb"'
echo "'aaa' \"bbb\""

sudo su enzotib -c 'echo \'\'\''aaa'\''\'\'\'' "bbb"'\'
sudo su enzotib -c 'echo "'\''aaa'\'' \"bbb\""'

sudo su enzotib -c "echo \\''aaa'\\'' \"bbb\"'"
sudo su enzotib -c "echo \"'aaa' \\\"bbb\\\"\""

10

在shell中转义引号的简单示例:

$ echo 'abc'\''abc'
abc'abc
$ echo "abc"\""abc"
abc"abc

通过完成已经打开的一个('),放置转义的一个(\'),然后打开另一个(')来完成此操作。

或者:

$ echo 'abc'"'"'abc'
abc'abc
$ echo "abc"'"'"abc"
abc"abc

通过完成已打开的一个('),在另一个引号("'")中放置引号,然后再打开另一个('),来完成此操作。

相关:如何在单引号字符串中转义单引号?在stackoverflow SE


1

接受的答案适用于简单(一级)引用:

$ echo $'\'single quote phrase\' "double quote phrase"'
'single quote phrase' "double quote phrase"

为了使命令生效,您需要引用两次。
该脚本可以完成所有工作:

#!/bin/bash

quote () { 
    local quoted=${1//\'/\'\\\'\'};
    printf "'%s'" "$quoted"
}

read -r line <<-\_line_to_quote_
'single quote phrase' "double quote phrase"
_line_to_quote_

quote "$line"; echo
quote "echo $(quote "$line")"; echo

执行脚本以获取:

$ script
''\''single quote phrase'\'' "double quote phrase"'
'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

第一行适用于简单的回显:

$ echo ''\''single quote phrase'\'' "double quote phrase"'
'single quote phrase' "double quote phrase"

第二行适用于双引号命令:

sudo su USER -c 'echo '\'''\''\'\'''\''single quote phrase'\''\'\'''\'' "double quote phrase"'\'''

-3

回显“我是学生”无效。但是以下工作原理:

在bash的手册页中回显$'I \'ma student':

即使在单引号之前加反斜杠,也不能在单引号之间引起单引号。.... $'string'形式的单词经过特殊处理。该单词扩展为字符串,并按ANSI C标准的规定替换反斜杠转义字符。


6
这不会为现有答案增加任何内容。
jasonwryan
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.