8wDlpd.png
8wDFp9.png
8wDEOx.png
8wDMfH.png
8wDKte.png

Bash 中单引号和双引号的区别

Shaul Behr 2月前

149 0

在 Bash 中,单引号 ('') 和双引号 (\'\') 有什么区别?

) 和双引号 ( '' ) "" 有什么区别

帖子版权声明 1、本帖标题:Bash 中单引号和双引号的区别
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Shaul Behr在本站《linux》版块原创发布, 转载请注明出处!
最新回复 (0)
  • 标题说的是 Bash,但这实际上适用于任何与 Bourne 兼容的 shell(经典的 Bourne shell、POSIX

  • 单引号不会插入任何内容,但双引号会。例如:变量、反引号、某些 \ 转义符等。

    例子:

    $ echo "$(echo "upg")"
    upg
    $ echo '$(echo "upg")'
    $(echo "upg")
    

    Bash 手册中有这样的说法:

    3.1.2.2 单引号

    将字符括在单引号 ( ' ) 中可保留引号内每个字符的字面值。单引号之间不能出现单引号,即使前面有反斜杠。

    3.1.2.3 双引号

    将字符括在双引号 ( " ) 中会保留引号内所有字符的文字值,但 、 和 除外 $ , ` , \ (当启用历史扩展时) ! 。字符 $ ` 在双引号内保留其特殊含义(请参阅 Shell 扩展 )。反斜杠仅在后跟以下字符之一时才保留其特殊含义: $ , ` , " , \ 、 或换行符。在双引号中,后跟以下字符之一的反斜杠将被删除。前面没有特殊含义的字符的反斜杠保持不变。可以在双引号内通过在双引号前面加上反斜杠来引用双引号。如果启用,则将执行历史扩展,除非 ! 使用反斜杠对双引号中出现的 进行转义。 前面的反斜杠 ! 不会被删除。

    特殊参数 * @ 在双引号中具有特殊含义(参见 Shell 参数扩展 )。

  • 对于那些不知道“interpolate”是什么意思的人:en.wikipedia.org/wiki/String_interpolation

  • 当您使用 git 提供的 git_prompt 时,他们建议像这样使用 PS1='[\u@\h \W$(__git_ps1 \' (%s)\')]\$ ', git prompt,根据这个不应该工作。PS# 变量有什么特别之处吗?或者如果它不进行插值,为什么它会起作用。

  • @ekiim 那个确切的文本被设置(未更改)到 PS1 中。尝试 echo $PS1 来了解我的意思。但是 PS1 在显示之前会被评估(请参阅 bash 手册页中的 PROMPTING 部分)。要测试这一点,请尝试 PS1='$X'。您将没有提示。然后运行 ​​X=foo,您的提示突然变成了 \'foo\'(如果 PS1 在设置时被评估而不是显示,您仍然不会有提示)。

  • Roe 2月前 0 只看Ta
    引用 7

    注意:$ name='O'Hara' 不合法,但 $ name='O'\''Hara' 可以。即使单引号之间的单引号不合法,您也可以通过将每个 ' 替换为 '\'' 而不带空格来将其转义。

  • 在此上下文中,另请参阅:.com/questions/16033158/... 和 .com/a/16033290/2153622。

  • 接受的答案 很棒 。我正在制作一个表格,帮助快速理解主题。解释涉及一个简单的变量 a 以及一个索引数组 arr .

    如果我们设定

    a=apple      # a simple variable
    arr=(apple)  # an indexed array with a single element
    

    然后 echo 第二列中的表达式,我们将得到第三列中显示的结果/行为。第四列解释了该行为。

    # 表达 结果 评论
    1 "$a" apple 变量在内部扩展 ""
    2 '$a' $a 变量不在内部扩展 ''
    3 "'$a'" 'apple' '' 里面没有特殊含义 ""
    4 '"$a"' "$a" "" 在内部按字面意思处理 ''
    5 '\'' p7 无法逃脱 ' '' 使用 "'" $'\'' (ANSI-C 引用)
    6 "red$arocks" red $arocks 不扩大 $a ;用于 ${a}rocks 保存 $a
    7 "redapple$" redapple$ $ 后面没有变量名,计算结果为 $
    8 '\"' \" \ 里面没有特殊含义 ''
    9 "\'" \' \' 在内部解释 "" ,但对 '
    10 "\"" " \" 在内部解释 ""
    11 "*" * glob 在内部不起作用 "" ''
    12 "\t\n" \t\n \t 并且 \n "" 内部没有特殊含义 '' ;使用 ANSI-C 引用
    十三 "`echo hi`" hi `` $() 在内部进行评估 "" (反引号保留在实际输出中)
    14 '`echo hi`' `echo hi` `` 并且 $() 不在内部进行评估 '' (反引号保留在实际输出中)
    15 '${arr[0]}' ${arr[0]} 无法在内部进行数组访问 ''
    16 "${arr[0]}" apple 数组访问在内部工作 ""
    17 $'$a\'' $a' 单引号可以在 ANSI-C 引用中转义
    18 "$'\t'" $'\t' ANSI-C 引用不被解释 ""
    19 '!cmd' !cmd 历史扩展字符 '!' 被忽略 ''
    20 "!cmd" cmd args 扩展到最近匹配的命令 "cmd"
    21 $'!cmd' !cmd 历史扩展字符 '!' 被忽略

    参见:

    • ANSI-C 使用 $'' 引用 - GNU Bash 手册
    • 使用 $\'\' 进行区域设置翻译 - GNU Bash 手册
    • 报价的三点公式
  • Amir 2月前 0 只看Ta
    引用 10

    接受的答案最后说,特殊参数 * 和 @ 在双引号中具有特殊含义,那么 \'*\' 怎么会得到 * 呢?

  • 引用 11

    @Karl-AnderoMere,因为在这种情况下它们根本没有作为参数扩展。'$@' 和 '$*' 是参数扩展。'@' 和 '*' 不是。

  • 我只想指出,在 bash 中“简单变量”也是数组,也就是说 echo $a 与上面例子中的 echo ${a[0]} 相同

  • @codeforester 第 3 点,您说 ' 在 \ 内没有特殊含义,但根据 GNU 手册: \'字符 '$' 和 ''' 在双引号内保留其特殊含义\'。 ' 的特殊含义是保留 $ 的文字值,答案应该是 $a。为什么不是这样?

  • 引用 14

    Csh 样式的历史记录引用可能最好关闭;它们不是很有用,关闭它们可以帮助您避免因未加引号的感叹号而出现令人讨厌的事件未找到错误消息。请参阅 .com/questions/11816122/echo-fails-event-not-found

  • 如果您指的是回显某些内容时发生的情况,单引号将逐字回显它们之间的内容,而双引号将评估它们之间的变量并输出变量的值。

    例如,

    #!/bin/sh
    MYVAR=sometext
    echo "double quotes gives you $MYVAR"
    echo 'single quotes gives you $MYVAR'
    

    将得到如下结果:

    double quotes gives you sometext
    single quotes gives you $MYVAR
    
  • Slai 2月前 0 只看Ta
    引用 16

    其他人解释得很好,我只想提供一些简单的例子。

    单引号 ,以防止 shell 解释任何特殊字符。美元符号、空格、& 符号、星号和其他特殊字符在单引号内时都会被忽略。

    echo 'All sorts of things are ignored in single quotes, like $ & * ; |.'
    

    它将给出这个:

    All sorts of things are ignored in single quotes, like $ & * ; |.
    

    唯一不能放在单引号内的是单引号。

    双引号的 作用与单引号类似,但双引号仍允许 shell 解释美元符号、反引号和反斜杠。众所周知,反斜杠会阻止解释单个特殊字符。如果需要将美元符号用作文本而不是变量,则双引号内的双引号非常有用。它还允许对双引号进行转义,这样它们就不会被解释为引号字符串的结尾。

    echo "Here's how we can use single ' and double \" quotes within double quotes"
    

    它将给出这个:

    Here's how we can use single ' and double " quotes within double quotes
    

    还可能注意到,双引号内的撇号会被忽略,否则撇号会被解释为引号字符串的开头。但是,双引号内的变量会被解释并替换为其值。

    echo "The current Oracle SID is $ORACLE_SID"
    

    它将给出这个:

    The current Oracle SID is test
    

    反引号 与单引号或双引号完全不同。反引号并非用于阻止解释特殊字符,而是强制执行其括起来的命令。执行括起来的命令后,其输出将替换原始行中的反引号。通过示例可以更清楚地了解这一点。

    today=`date '+%A, %B %d, %Y'`
    echo $today
    

    它将给出这个:

    Monday, September 28, 2015
    
  • 我喜欢这个答案,因为它清楚地说明了唯一不能放在单引号中的是单引号。我再补充一下,反引号已被弃用,而 $() 与 POSIX 兼容,因此您应该更喜欢后者。

  • @Ben 是的,$(...) 和 `...` 是一样的。除了前者嵌套,后者不嵌套。

  • 由于这是处理 Bash 中的引号时事实上的答案,因此在处理 shell 中的算术运算符时,我将补充上述答案中遗漏的一点。

    Bash shell 支持两种方式进行算术运算,一种由内置 let 命令定义,另一种由 $((..)) 运算符定义。前者计算算术表达式,而后者更像是复合语句。

    重要的是要理解,使用的算术表达式 let 会像任何其他 shell 命令一样进行分词、路径名扩展。因此需要进行适当的引用和转义。

    使用时请参见此示例 let

    let 'foo = 2 + 1'
    echo $foo
    3
    

    在这里使用单引号是完全没问题的,因为这里不需要变量扩展。考虑以下情况

    bar=1
    let 'foo = $bar + 1'
    

    它会失败,因为 $bar 下面的单引号不会 扩展 ,需要用双引号引起来

    let 'foo = '"$bar"' + 1'
    

    这应该是原因之一,应该 $((..)) 始终考虑使用 而不是使用 let 。因为在它里面,内容不受分词的影响。前面的示例使用 let 可以简单地写成

    (( bar=1, foo = bar + 1 ))
    

    一定要记住不要使用 $((..)) 单引号

    虽然 $((..)) 可以使用双引号,但这样做没有任何用处,因为它 不能 包含需要双引号的内容。只需确保它不是单引号即可。

    printf '%d\n' '$((1+1))'
    -bash: printf: $((1+1)): invalid number
    printf '%d\n' $((1+1))
    2
    printf '%d\n' "$((1+1))"
    2
    

    也许在单引号字符串中使用运算符的某些特殊情况下 $((..)) ,您需要以一种方式插入引号,即运算符要么不加引号,要么放在双引号中。例如,考虑这样一种情况,当您试图在语句中使用运算符 curl 来在每次发出请求时传递计数器时,请执行

    curl http://myurl.com --data-binary '{"requestCounter":'"$((reqcnt++))"'}'
    

    注意里面嵌套双引号的使用,如果没有双引号,文字字符串 $((reqcnt++)) 就会传递给 requestCounter 字段。

  • Charles Duffy 在这里也很好地说明了双引号 $((...)) 的重要性。例如,这可能有点偏执,而且 IFS=0 的可能性很小,但肯定并非不可能 :)

返回
作者最近主题: