Bash 里的转义序列
在 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 里的转义序列的更多相关文章
- bash里,echo对换行符的处理
echo -e "#include <stdio.h>\nint main()\n{\n printf(\"hello world\\\n\");\n ret ...
- bash里wget失败
直接使用wget是可以的,然而在shell脚本里却不行,后来发现原来是换行符的问题,编辑器默认的是\r\n,一不留神,自己把自己坑了
- [Bash Shell] Shell学习笔记
1. Shell简介 Shell本身是一个用C语言编写的程序,它是用户使用Unix/Linux的桥梁,用户的大部分工作都是通过Shell完成的.Shell既是一种命令语言,又是一种程序设计语言.作为命 ...
- bash/shell编程学习(2)
先来复习上节重定向的用法: 1.快速清空文件 cat demo.txt < /dev/null 注:linux中有一个经典名言[一切皆文件],/dev/null可以认为是一个特殊的空文件,更形象 ...
- 解决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 ...
- Bash 为何要发明 shopt 命令
在 Bash 中,有两个内置命令用来控制 Bash 的各种可配置行为的开关(打开或关闭),这些开关称之为选项(option).其中一个命令是 set,set 命令有三种功能:显示所有的变量和函数:修改 ...
- Bash 中同名的内部命令和外部命令
昨天有个人在 bug-bash 上问:为什么 [ --help 没有输出帮助信息.有人回答他了,原因是 coreutils 提供的 [ 命令才接受 --help 选项,Bash 自己的 [ 命令不接受 ...
- Bash 中的环境变量
在 Bash 里,可以通过 export 命令查看当前 Shell 进程的环境变量,这些环境变量一些是 Bash 自己创建的,还有一些是 Bash 从父进程继承来的,然而需要注意的是,父进程传给 Ba ...
- Bash 中 SHLVL 变量为 1000 的时候
SHLVL 环境变量代表 Shell 嵌套执行的深度. $ echo $SHLVL 1 $ bash $ echo $SHLVL 2 $ bash $ echo $SHLVL 3 在 Bash 里,这 ...
随机推荐
- mysql5.7 root password change
mysqld_safe --skip-grant-tables &update mysql.user set authentication_string=password('Root_1234 ...
- 学习大神笔记之 “MyBatis学习总结(一)”
1.准备工作 软件:eclipse. mysql .navicat for mysql 包:mybatis-3.1.1.jar mysql-connector-java-5.1.7-bin.jar ...
- java进程占用CPU资源过高分析脚本
#!/bin/bash #输入占用CPU较高的进程号 pid=$ if [ -z $pid ] then echo "PID is NULL" exit fi #找到该进程中占用较 ...
- UVA - 1625 Color Length[序列DP 代价计算技巧]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- LeetCode Intersection of Two Arrays
原题链接在这里:https://leetcode.com/problems/intersection-of-two-arrays/ 题目: Given two arrays, write a func ...
- nodeJS基础08:读取图片
1.读取图片 //server.js var http = require("http"); var readImage = require("./readImage&q ...
- 了解 JS 原型
原型概念 当创建了一个函数时,就会根据一组特定的规则为该函数创建一个 prototype 属性,这个属性指向函数的原型对象.在默认情况下,所有原型对象都会自动获得一个constructor 的属性 这 ...
- C#多线程同步事件及等待句柄AutoResetEvent 和 ManualResetEvent
最近捣鼓了一下多线程的同步问题,发现其实C#关于多线程同步事件处理还是很灵活,这里主要写一下,自己测试的一些代码,涉及到了AutoResetEvent 和 ManualResetEvent,当然还有也 ...
- CSS继承的特殊性
p{color:red;} .first{color:green;} <p class="first">三年级时,我还是一个<span>胆小如鼠</s ...
- 使用s3cmd操作ceph rgw
安装1.sudo apt-get install -y python-pip sudo pip install s3cmd 2. sudo apt-get install s3cmd 配置 s3c ...