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

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

Shaul Behr 2月前

169 0

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

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

帖子版权声明 1、本帖标题:Bash 中单引号和双引号的区别
    本站网址:http://xjnalaquan.com/
2、本网站的资源部分来源于网络,如有侵权,请联系站长进行删除处理。
3、会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。
4、本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报
5、站长邮箱:yeweds@126.com 除非注明,本帖由Shaul Behr在本站《linux》版块原创发布, 转载请注明出处!
最新回复 (0)
  • @tripleee 我只是想用最简单的术语来解释。我想清晰的解释比使用正确的“同义词”更重要。它确实帮助了不使用“插值”一词的人。

  • 您所说的“转换或翻译”通常称为插值。表达式“foo $bar baz”只是文字字符串 foo $bar baz,而“foo $bar baz”将变量 bar 的值插入文字符号 foo 和 baz 之间的字符串中,中间有空格。

  • 在我看来,这是一个简短而简洁的答案,没有过多的冗长,我很容易理解。当说到翻译/转换时,它们的意思是双引号将扩展变量,而单引号不会扩展变量。

  • ' ' 的使用有明显的区别 " " .

    ' ' 用于任何事物时,不会进行“转换或翻译”。它会按原样打印。

    有了 " " ,它所包围的一切,都会被“翻译或转化”为它的价值。

    我所说的翻译/转换是指:单引号内的任何内容都不会被“翻译”为其值。它们将被视为在引号内。例如: a=23 ,然后 echo '$a' 在标准输出上 $a 产生 echo "$a" 将在标准输出上产生 23

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

  • 由于这是处理 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 字段。

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

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

  • Slai 2月前 0 只看Ta
    引用 10

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

    单引号 ,以防止 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
    
  • 如果您指的是回显某些内容时发生的情况,单引号将逐字回显它们之间的内容,而双引号将评估它们之间的变量并输出变量的值。

    例如,

    #!/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
    
  • 引用 12

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

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

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

  • 引用 15

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

  • Amir 2月前 0 只看Ta
    引用 16

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

  • 接受的答案 很棒 。我正在制作一个表格,帮助快速理解主题。解释涉及一个简单的变量 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 手册
    • 报价的三点公式
  • 引用 18

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

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

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

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

返回
作者最近主题: