Skip to content
SRE运维进阶之路SRE运维进阶之路
github icon
    • 第一部分 初见shell

      • 第一章 为什么使用shell编程
        • 第二章 和Sha-Bang(#!)一起出发

          • 2.1 调用一个脚本
            • 2.2 牛刀小试
          • 第二部分 shell基础

            • 第三章 特殊字符
              • 第四章 变量与参数

                • 4.1 变量替换
                  • 4.2 变量赋值
                    • 4.3 Bash变量是弱类型的
                      • /code/shell/part2/04_4_special_variable_types
                      • 第五章 引用

                        • 5.1 引用变量
                          • 5.2 转义
                          • 第六章 退出与退出状态
                            • 第七章 测试

                              • 7.1 测试结构
                                • 7.2 文件测试操作
                                  • 7.3 其他比较操作
                                    • 7.4 嵌套 if/then 条件测试
                                      • 7.5 牛刀小试
                                      • 第八章 运算符相关话题

                                        • 8.1 运算符
                                          • 8.2 数字常量
                                            • 8.3 双圆括号结构
                                              • 8.4 运算符优先级
                                            • 第三部分 shell进阶

                                              • 第九章 换个角度看变量

                                                • 9.1 内部变量
                                                  • 9.2 变量类型标注:declare 与 typeset
                                                    • 9.2.1 declare 的另类用法
                                                      • 9.3 $RANDOM:生成随机数
                                                      • 第十章 变量处理

                                                        • 10.1 字符串处理
                                                          • 10.1.1 使用 awk 处理字符串
                                                            • 10.1.2 参考资料
                                                              • 10.2 参数替换
                                                              • 第十一章 循环与分支

                                                                • 11.1 循环
                                                                  • 11.2 嵌套循环
                                                                    • 11.3 循环控制
                                                                      • 11.4 测试与分支
                                                                      • 第十二章 命令替换
                                                                        • 第十三章 算术扩展
                                                                        • 第四部分 命令
                                                                          • 第五部分 高级话题

                                                                            • 18 正则表达式

                                                                              • 18.1 正则表达式简介
                                                                                • 18.2文件名替换
                                                                                  • 18.3 正则表达式对照表
                                                                                  • 19 嵌入文档
                                                                                    • 20 I/O 重定向

                                                                                      • 20.1 使用 exec
                                                                                        • 20.2 重定向代码块
                                                                                          • 20.3 应用程序
                                                                                          • 第二十一章 子shell
                                                                                            • 第二十二章. 限制模式的Shell
                                                                                              • 第二十三章. 进程替换
                                                                                                • 24 函数

                                                                                                  • 24.1 复杂函数和函数复杂性
                                                                                                    • 24.2 局部变量
                                                                                                      • 24.3 不使用局部变量的递归
                                                                                                      • 25. 别名
                                                                                                        • 26. 列表结构
                                                                                                          • 27 数组
                                                                                                            • 30 网络编程
                                                                                                              • 33 选项
                                                                                                                • 第34章 陷阱
                                                                                                                  • 第36章 杂项
                                                                                                                    • echo命令
                                                                                                                    • 第六部分 Google Shell 风格指南
                                                                                                                    • 前端学习笔记

                                                                                                                      5.1 引用变量

                                                                                                                      author iconLinuxStorycalendar icon2021年5月11日category icon
                                                                                                                      • Linux
                                                                                                                      tag icon
                                                                                                                      • Bash
                                                                                                                      timer icon大约 3 分钟

                                                                                                                      # 5.1 引用变量

                                                                                                                      引用变量时,通常建议将变量包含在双引号中。因为这样可以防止除 $,`(反引号)和\(转义符)之外的其他特殊字符被重新解释。[1]在双引号中仍然可以使用$引用变量("$variable"),也就是将变量名替换为变量值(详情查看样例 4-1)。

                                                                                                                      使用双引号可以防止字符串被分割。[2]即使参数中拥有很多空白分隔符,被包在双引号中后依旧是算作单一字符。

                                                                                                                      List="one two three"
                                                                                                                      
                                                                                                                      for a in $List     # 空白符将变量分成几个部分。
                                                                                                                      do
                                                                                                                        echo "$a"
                                                                                                                      done
                                                                                                                      # one
                                                                                                                      # two
                                                                                                                      # three
                                                                                                                      
                                                                                                                      echo "---"
                                                                                                                      
                                                                                                                      for a in "$List"   # 在单一变量中保留所有空格。
                                                                                                                      do #     ^     ^
                                                                                                                        echo "$a"
                                                                                                                      done
                                                                                                                      # one two three
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      12
                                                                                                                      13
                                                                                                                      14
                                                                                                                      15
                                                                                                                      16
                                                                                                                      17

                                                                                                                      下面是一个更加复杂的例子:

                                                                                                                      variable1="a variable containing five words"
                                                                                                                      COMMAND This is $variable1    # 带上7个参数执行COMMAND命令:
                                                                                                                      # "This" "is" "a" "variable" "containing" "five" "words"
                                                                                                                      
                                                                                                                      COMMAND "This is $variable1"  # 带上1个参数执行COMMAND命令:
                                                                                                                      # "This is a variable containing five words"
                                                                                                                      
                                                                                                                      
                                                                                                                      variable2=""    # 空值。
                                                                                                                      
                                                                                                                      COMMAND  $variable2 $variable2 $variable2
                                                                                                                                      # 不带参数执行COMMAND命令。
                                                                                                                      COMMAND "$variable2" "$variable2" "$variable2"
                                                                                                                                      # 带上3个参数执行COMMAND命令。
                                                                                                                      COMMAND "$variable2 $variable2 $variable2"
                                                                                                                                      # 带上1个参数执行COMMAND命令(2空格)。
                                                                                                                      
                                                                                                                      # 感谢 Stéphane Chazelas。
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      12
                                                                                                                      13
                                                                                                                      14
                                                                                                                      15
                                                                                                                      16
                                                                                                                      17
                                                                                                                      18

                                                                                                                      info 当字符分割或者保留空白符出现问题时,才需要在echo语句中用双引号包住参数。

                                                                                                                      样例 5-1. 输出一些奇怪的变量

                                                                                                                      #!/bin/bash
                                                                                                                      # weirdvars.sh: 输出一些奇怪的变量
                                                                                                                      
                                                                                                                      echo
                                                                                                                      
                                                                                                                      var="'(]\\{}\$\""
                                                                                                                      echo $var        # '(]\{}$"
                                                                                                                      echo "$var"      # '(]\{}$"     没有任何区别。
                                                                                                                      
                                                                                                                      echo
                                                                                                                      
                                                                                                                      IFS='\'
                                                                                                                      echo $var        # '(] {}$"     \ 被转换成了空格,为什么?
                                                                                                                      echo "$var"      # '(]\{}$"
                                                                                                                      
                                                                                                                      # 上面的例子由 Stephane Chazelas 提供。
                                                                                                                      
                                                                                                                      echo
                                                                                                                      
                                                                                                                      var2="\\\\\""
                                                                                                                      echo $var2       #   "
                                                                                                                      echo "$var2"     # \\"
                                                                                                                      echo
                                                                                                                      # 但是...var2="\\\\"" 不是合法的语句,为什么?
                                                                                                                      var3='\\\\'
                                                                                                                      echo "$var3"     # \\\\
                                                                                                                      # 强引用是可以的。
                                                                                                                      
                                                                                                                      
                                                                                                                      # ************************************************************ #
                                                                                                                      # 就像第一个例子展示的那样,嵌套引用是允许的。
                                                                                                                      
                                                                                                                      echo "$(echo '"')"           # "
                                                                                                                      #    ^           ^
                                                                                                                      
                                                                                                                      
                                                                                                                      # 在有些时候这种方法非常有用。
                                                                                                                      
                                                                                                                      var1="Two bits"
                                                                                                                      echo "\$var1 = "$var1""      # $var1 = Two bits
                                                                                                                      #    ^                ^
                                                                                                                      
                                                                                                                      # 或者,可以像 Chris Hiestand 指出的那样:
                                                                                                                      
                                                                                                                      if [[ "$(du "$My_File1")" -gt "$(du "$My_File2")" ]]
                                                                                                                      #     ^     ^         ^ ^     ^     ^         ^ ^
                                                                                                                      then
                                                                                                                        ...
                                                                                                                      fi
                                                                                                                      # ************************************************************ #
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10
                                                                                                                      11
                                                                                                                      12
                                                                                                                      13
                                                                                                                      14
                                                                                                                      15
                                                                                                                      16
                                                                                                                      17
                                                                                                                      18
                                                                                                                      19
                                                                                                                      20
                                                                                                                      21
                                                                                                                      22
                                                                                                                      23
                                                                                                                      24
                                                                                                                      25
                                                                                                                      26
                                                                                                                      27
                                                                                                                      28
                                                                                                                      29
                                                                                                                      30
                                                                                                                      31
                                                                                                                      32
                                                                                                                      33
                                                                                                                      34
                                                                                                                      35
                                                                                                                      36
                                                                                                                      37
                                                                                                                      38
                                                                                                                      39
                                                                                                                      40
                                                                                                                      41
                                                                                                                      42
                                                                                                                      43
                                                                                                                      44
                                                                                                                      45
                                                                                                                      46
                                                                                                                      47
                                                                                                                      48
                                                                                                                      49
                                                                                                                      50

                                                                                                                      单引号(' ')与双引号类似,但是在单引号中不能引用变量,因为 $ 不再具有特殊含义。在单引号中,除'之外的所有特殊字符都将会被直接按照字面意思解释。可以认为单引号(“全引用”)是双引号(“部分引用”)的一种更严格的形式。

                                                                                                                      extra 因为在单引号中转义符(\)都已经按照字面意思解释了,因此尝试在单引号中包含单引号将不会产生你所预期的结果。

                                                                                                                      echo "Why can't I write 's between single quotes"
                                                                                                                      >
                                                                                                                      echo
                                                                                                                      >
                                                                                                                      # 可以采取迂回的方式。
                                                                                                                      echo 'Why can'\''t I write '"'"'s between single quotes'
                                                                                                                      #    |-------|  |----------|   |-----------------------|
                                                                                                                      # 由三个单引号引用的字符串,再加上转义以及双引号包住的单引号组成。
                                                                                                                      >
                                                                                                                      # 感谢 Stéphane Chazelas 提供的例子。
                                                                                                                      
                                                                                                                      1
                                                                                                                      2
                                                                                                                      3
                                                                                                                      4
                                                                                                                      5
                                                                                                                      6
                                                                                                                      7
                                                                                                                      8
                                                                                                                      9
                                                                                                                      10

                                                                                                                      1. 在命令行里,如果双引号包含了 "!" 将会产生错误。这是因为shell将其解释为查看历史命令。而在脚本中,因为历史机制已经被关闭,所以不会产生这个问题。
                                                                                                                        我们更加需要注意的是在双引号中 \ 的反常行为,尤其是在使用 echo -e 命令时。

                                                                                                                        bash$ echo hello\!
                                                                                                                        hello!
                                                                                                                        bash$ echo "hello\!"
                                                                                                                        hello\!


                                                                                                                        bash$ echo \
                                                                                                                        >
                                                                                                                        bash$ echo "\"
                                                                                                                        >
                                                                                                                        bash$ echo \a
                                                                                                                        a
                                                                                                                        bash$ echo "\a"
                                                                                                                        \a


                                                                                                                        bash$ echo x\ty
                                                                                                                        xty
                                                                                                                        bash$ echo "x\ty"
                                                                                                                        x\ty

                                                                                                                        bash$ echo -e x\ty
                                                                                                                        xty
                                                                                                                        bash$ echo -e "x\ty"
                                                                                                                        x y
                                                                                                                        在 echo 后的双引号中一般会转义 \。并且 echo -e 会将 "\t" 解释成制表符。
                                                                                                                        (感谢 Wayne Pollock 提出这些;感谢Geoff Lee 与 Daniel Barclay 对此做出的解释。) ↩︎

                                                                                                                      2. 字符分割(word splitting)在本文中的意思是指将一个字符串分割成独立的、离散的变量。 ↩︎

                                                                                                                      edit icon编辑此页open in new window
                                                                                                                      上次编辑于: 2022/4/27 15:33:00
                                                                                                                      贡献者: clay-wangzhi
                                                                                                                      下一页
                                                                                                                      5.2 转义
                                                                                                                      备案号:冀ICP备2021007336号
                                                                                                                      Copyright © 2023 LinuxStory