Shell Script - Special Character (特殊符号) ============================================================================== .. contents:: 目录 :depth: 1 :local: 参考资料: - Shell 特殊字符大全: https://blog.csdn.net/K346K346/article/details/51819236 - https://www.tldp.org/LDP/abs/html/quotingvar.html - 单引号: ``'`` - 双引号: ``"`` - 反引号: ````` - 转义符: ``\`` - 小括号: ``()`` - 中括号: ``[]`` - 大括号: ``{}`` 特殊变量``~`` ------------------------------------------------------------------------------ 和环境变量 $HOME, 当前用户的主目录. .. code-block:: bash # 进入当前用户的主目录, 等效于 cd ~ ~ # 查看当前用户的主目录的绝对路径 echo ~ # 查看当前目录, 等效于 pwd ~+ # 查看前一个工作目录 echo ~- # 回到前一个工作目录, 只能回退一步, 不能回退多步 - ``$`` 变量替换符 ------------------------------------------------------------------------------ ``${:-}``:: # 用法 ${var:-word}. # 表示如果变量 var 为空或已被删除 (unset), 那么返回 word, 但不改变 var 的值. # 如果已经被定义, 则返回 ${var}. echo "${MY_VAR:-hello}" # 因为 MY_VAR 没有被定义, 所以返回 hello ``${:+}``:: # 用法 ${var:+word}. # 如果变量 var 被定义, 那么返回 word, 但不改变 var 的值. # 如果为空或已被删除 (unset), 则返回空 echo "${MY_VAR:+hello}" # 因为 MY_VAR 没有被定义, 所以返回空 ``${:=}``:: # 用法 ${var:=word}. # 如果变量 var 为空或已被删除(unset), 那么返回 word, 并将 var 的值设置为 word. # 如果已经被设置, 则并不设置, 并返回原有的值 echo "${MY_VAR:=hello}" # 因为没有被定义, 所以返回 hello, 并且 $MY_VAR 有值了 ``${:?}``:: # 用法 ${var:?message}. # 如果变量 var 为空或已被删除(unset), 那么将消息 message 送到标准错误输出. # 可以用来检测变量 var 是否可以被正常赋值. 若此替换出现在 Shell 脚本中, 那么脚本将停止运行. MY_VAR="alice" echo "${MY_VAR:?hello}" # 因为已经被定义, 所以返回 alice ``${#}``:: # 用法 ${#var}. 获取字符串变量var的长度. MY_VAR="alice" echo ${#MY_VAR} # 返回 5 echo ${#${MY_VAR}} # 返回 5 echo "${#${MY_VAR}}" # 返回 5 ``${:}`` 或 ``${::}``:: # 字符串提取 # 用法${var:n}. # 若n为正数, n从0开始, 表示在变量var中提取第n个字符到末尾的所有字符. # 若n为负数, 提取字符串最后面n的绝对值个字符 # 使用时在冒号后面加空格或一个算术表达式或整个num加上括号, 如 ${var: -2}, ${var:1−3} 或 ${var:(-2)} 均表示提取字符串最后两个字符 NOW="1978-01-02 03:04:05" echo "${NOW:11}" # 03:04:05 echo "${NOW:0:10}" # 1978-01-02 单引号 ``'`` 和 双引号 ``"`` 的含义 ------------------------------------------------------------------------------ 单引号 ``'`` 和 双引号 ``"`` 都是为了解决空格应该被解释为字符串, 还是命令分隔符的问题. 比如你想定义一个变量: ``name=David John``, 这样程序会报错. 正确的做法是 ``name="David John"`` 或是 ``name='David John'``. 单引号 ``'`` 和 双引号 ``"`` 的区别 ------------------------------------------------------------------------------ 单引号中除了 ``'`` 本身, 其他所有特殊字符的特殊含义都被剥夺了. 双引号相当于没有那么严格的单引号, 除了 ``$`` 表示变量, ````` 表示命令替换, ``\`` 表示. 反引号 ````` 的含义 ------------------------------------------------------------------------------ 反引号表示命令替换, 也就是说, 反引号包含的内容会被当做命令来对待, 先执行一遍, 然后再跟外层命令合并. ``echo `ls``` 和 ``echo $(ls)`` 是完全等价的. 但是根据最新的 POSIX 规范, 反引号已经被逐渐抛弃, 而要求全部使用 ``$(...)``. 转义符 ``\`` 的含义 ------------------------------------------------------------------------------ 转移符 ``\`` 如果单独使用, 则是 **换行符**, 常用于非常长的命令, 例如:: $ cmd ... \ --option1=value1 \ --option2=value2 \ --option3=value3 而通常情况下, 转义符后面都是要跟一个其他字符的, 通常表示将后面跟着的的特殊符号作为普通字符解释. 例如 ``dollar="\$"``. 而在 ``echo`` 和 ``sed`` 命令下, 则是表示特殊符号, 例如 ``\n`` 表示换行, ``\t`` 表示制表符. 其他特殊符号请看这里 https://www.tldp.org/LDP/abs/html/escapingsection.html 小括号 和 大括号 ------------------------------------------------------------------------------ - ``()`` 对一串命令 **重新开一个子 shell 执行** - ``{}`` 对一串命令 **在当前 shell 执行** - ``()`` 和 ``{}`` 都是把一串的命令放在括号里面, 并且 **命令之间用** ``;`` **号隔开** - ``()`` 最后一个命令 **可以不用分号** - ``{}`` 最后一个命令 **必须要用分号** - ``{}`` 的第一个命令和左括号之间必须要有一个空格 - ``()`` 里的各命令不必跟括号之间有空格 - ``()`` 和 ``{}`` 中括号里面的某个命令的重定向只影响该命令, 但括号外的重定向则影响到括号里的所有命令 中括号 和 双中括号 ------------------------------------------------------------------------------ 中括号: - ``[``, ``]`` 两个符号左右都要有空格分隔 - 内部操作符与操作变量之间要有空格: ``[ "a" == "b" ]`` - 字符串比较中, ``>`` ``<`` 需要写成 ``\>`` ``\<`` 进行转义 - ``[ ]`` 中字符串或者 ``${}`` 变量尽量使用 ``"`` 扩住, 以避免值未定义引用而出错 - ``[ ]`` 中可以使用 –a –o 进行逻辑运算 - ``[ ]`` 是bash 内置命令: ``[`` is a shell builtin 双中括号: - ``[[`` ``]]`` 两个符号左右都要有空格分隔 - 内部操作符与操作变量之间要有空格:如 ``[[ "a" = "b" ]]`` - 字符串比较中,可以直接使用 ``>`` ``<`` 无需转义 - ``[[ ]]`` 中字符串或者 ``${}`` 变量尽量使用 ``"`` 扩住, 如未使用 ``"`` 会进行模式和元字符匹配 - ``[[ ]]`` 内部可以使用 ``&&``, ``||`` 进行逻辑运算 - ``[[ ]]`` 是bash keyword: ``[[`` is a shell keyword``