在 Bash 里,一共有五个地方支持反斜杠开头的转义序列,包括两个内部命令 echo 和 printf 的参数里,字符串语法 $'...' 里,还有四个提示符变量 PS1-PS4 里,以及在 Readline 配置文件里(用来自定义键盘快捷键)。其中后两者不在本文的讨论范围内,我们只看看前三个命令/语法在对某些转义序列解释上的差异。

1. \?,\',\"

$'...' 会把反斜杠去掉,只分别输出问号,单引号,双引号这三个字符串本身,而 echo -e 会原样输出(保留反斜杠),也就是不把这三个东西当成转义序列。printf 要分两种情况来看,一种情况是转义序列出现在 printf 的格式字符串中,也就是出现在 printf 的第一个参数中,这种情况它的表现像 $'...',还有一种就是转义序列出现在与 printf 第一个参数里的 %b 格式指示符对应的随后的参数里的情况,这时候它的表现像 echo -e,下面看演示。

$ echo $'\?'$'\''$'\"'           # 反斜杠不见了

?'"

$ echo -e '\?'"\'"'\"'           # 原样输出

\?\'\"

$ printf '\?'"\'"'\"''\n'         # 表现的像 $'...'

?'"

$ printf '%b' '\?'"\'"'\"''\n'  # 表现的像 echo -e

\?\'\"

2. \nnn 和 \0nnn

$'...' 只支持 \nnn,而 echo -e 只支持 \0nnn。printf 还是要分两种情况来看,出现在格式字符串中的表现像 $'...',出现在 %b 的参数里是,同时支持 \nnn 和 \0nnn 两种形式,下面看演示。

$ echo $'\100' $'\0100'       # 第二个参数里的 \0100 被解释成了 \010 和 0,所以 echo 分别输出了 @,\010,0 这三个字符,第二个字符串就是 \b,它不可见

@ 0

$ echo -e '\100' '\0100'       # \100 原样输出

\100 @

$ printf '\100 \0100\n'        # \010 也就是退格符删掉了中间的空格,所以 @ 和 0 之间紧挨着

@0

$ printf '%b' '\100\0100\n'  # 两种语法都支持

@@

3. \c

$'...' 会把 \c 以及它后面的那个字符(x)合起来看成一个转义序列,解义后的值会是个控制字符(ascii 码在 0 到 31 之间的字符),其解义算法是这样的:chr(ord(x) & 31)。而 echo -e 会把 \c 看成是字符串的终结符号,在 \c 之后的所有字符都会被丢弃掉,对应于 c 语言字符串中表示字符串结尾的 \0 字符,其底层实现也的确是把 \c 解义成了 \0(Bash 是用 c 语言写的)。printf 还是要分两种情况来看,如果出现在格式字符串中,\c 会原样输出,如果出现在 %b 的参数里是,\c 的表现像 echo -e,下面看演示。

$ echo $'\c*'                     # \c* 解义 之后是 \n,所以下面会有两个空行

$ echo -e 'hello\cworld'      # world 以及最后的换行符都被吞掉了

hello

$ printf '\c*\n'                   # \c 原样输出

\c*

$ printf '%b' 'hello\cworld'  # 表现的和 echo -e 一样

hello

总结

上面讲的所有这些在 Bash Manual 里都有提到,只是有些点说的比较隐含。你只要知道这三种用来输出转义序列的命令/语法是有细微差别的就可以了,不要去尝试记忆这些差别,因为你可能一辈子也遇不上。同时在看 Bash Manual 的时候发现讲 $'...' 的章节漏掉了对 \? 这个转义序列的记载,虽然不是什么大事,但还是报了个 bug http://comments.gmane.org/gmane.comp.shells.bash.bugs/24127

Bash 里的转义序列的更多相关文章

  1. bash里,echo对换行符的处理

    echo -e "#include <stdio.h>\nint main()\n{\n printf(\"hello world\\\n\");\n ret ...

  2. [Bash Shell] Shell学习笔记

    1. Shell简介 Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的.Shell既是一种命令语言,又是一种程序设计语言.作为命 ...

  3. bash/shell编程学习(2)

    先来复习上节重定向的用法: 1.快速清空文件 cat demo.txt < /dev/null 注:linux中有一个经典名言[一切皆文件],/dev/null可以认为是一个特殊的空文件,更形象 ...

  4. 解决Scala Play框架在Git Bash运行的异常:Could not find configuration file ../framework/sbt/sbt.boot.properties

    Git Bash+ConEmu可以模拟Linux强大的命令行.不过在结合Scala和Play时,需要注意如下事项: 1. Scala的安装在64位操作系统下,默认会放在“C:\Program File ...

  5. Bash 为何要发明 shopt 命令

    在 Bash 中,有两个内置命令用来控制 Bash 的各种可配置行为的开关(打开或关闭),这些开关称之为选项(option).其中一个命令是 set,set 命令有三种功能:显示所有的变量和函数:修改 ...

  6. Bash 中同名的内部命令和外部命令

    昨天有个人在 bug-bash 上问:为什么 [ --help 没有输出帮助信息.有人回答他了,原因是 coreutils 提供的 [ 命令才接受 --help 选项,Bash 自己的 [ 命令不接受 ...

  7. Bash 中的环境变量

    在 Bash 里,可以通过 export 命令查看当前 Shell 进程的环境变量,这些环境变量一些是 Bash 自己创建的,还有一些是 Bash 从父进程继承来的,然而需要注意的是,父进程传给 Ba ...

  8. Bash 中 SHLVL 变量为 1000 的时候

    SHLVL 环境变量代表 Shell 嵌套执行的深度. $ echo $SHLVL 1 $ bash $ echo $SHLVL 2 $ bash $ echo $SHLVL 3 在 Bash 里,这 ...

  9. Bash脚本15分钟进阶指导

    首先声明这是网上摘来的.这里的技术技巧最初是来自谷歌的“Testing on the Toilet” (TOTT).这里是一个修订和扩增版本. 脚本安全 我的所有bash脚本都以下面几句为开场白: # ...

随机推荐

  1. 当忘记mysql数据库密码时如何进行修改

    因为长时间没有使用数据库了,或者把密码改完之后就忘了数据库密码,不能正常进入数据库,也无法修改密码,有一个简单的常用修改密码方式: 1.首先找到和打开mysql.exe和mysqld.exe所在的文件 ...

  2. 利用calc计算宽度

    width:calc(100% - 40px)可用 + - * / 进行计算(ie9+) 注:计算符号前后必须跟上空格.

  3. LAN-LAN FREE-SERVER FREE

    注:本文转自http://taotao1240.blog.51cto.com/731446/839702 CU上有个板块叫“存储备份”,可见存储和备份是紧紧联系的.在看备份的时候,经常能看到LAN f ...

  4. dede去掉当前位置position后面的箭头

    理论是,dede的当前位置标签{dedefield name='position'},结构是 "首页 > 主栏目 > 子栏目 > ",箭头符号字段数据都是在后台设 ...

  5. 小甲鱼python视频弟十一讲(课后习题)

    1.修改列表里的值 list1 = [,,[,,,[,,,,] list1[] = print(list1) list1[][][] = '?' print(list1) 2.列表的排序(sort) ...

  6. [JS]应用splice删除多元素时出现的坑

    ------------------------------------------------------------------------------------- 先看一个片段: var fr ...

  7. Swift 自动布局框架-SnapKit

    官方网址:http://snapkit.io/ Github: https://github.com/SnapKit/SnapKit SnapKit is a DSL to make Auto Lay ...

  8. dp - Google Code jam Qualification Round 2015 --- Problem B. Infinite House of Pancakes

    Problem B. Infinite House of Pancakes Problem's Link:   https://code.google.com/codejam/contest/6224 ...

  9. 剑指Offer07 斐波那契数列

    /************************************************************************* > File Name: 07_Fibona ...

  10. RecyclerView 结合 CardView 使用

    准备工作:导入 1.activity_mian.xml <android.support.v7.widget.RecyclerView android:id="@+id/recycle ...