echo的奇思妙想

echo ‘hello world’

最近为了优化七牛云图床上传流程,自己研究了 shell 脚本写了一些自动化脚本(稍后会公布出来),已经到了写完脚本沉淀知识的阶段.一个意外的代码实验让我改变了主意,有了这篇文章.

当时我想做一个很小的尝试,在mac 的终端把一小段(准确说是两行)代码重定向到文件中,写了 N 多遍,竟然都没有达到我想要的结果,我期待的是利用pwd 输出当前位置的绝对路径,把这个路径输出出来.这一段代码需要直接从 shell 终端中写进一个叫tempfile的文件中.

第一句

1
2
3
4
5
6
7
echo "my_Path=$(pwd)" > tempfile            #1
echo 'my_Path=$(pwd)' > tempfile #2
echo my_Path=${pwd} > tempfile #3
echo "my_Path=${pwd}" > tempfile #4
echo -n "my_Path=\$\{pwd\}" > tempfile #5
echo -n "my_Path=${pwd}" > tempfile #6
echo -n "my_Path=\${pwd}" > tempfile #7

第二句

1
2
3
4
echo $my_Path >> tempfile                   #8
echo -n "echo \$my_Path" >> tempfile #9
echo -n "\$my_Path" >> tempfile #10
echo "$my_Path" >> tempfile #11

在开始这个小故事前,我知道echo的基本用法,也大致知道-n 参数的作用,也知道转义字符的作用.但是在这里的数个细节的叠加下,事情变得微妙起来.

大括号和小括号之争

第一句的尝试中#3和#4的内容是错误的,{}并不适合用在对命令的边界确认上.需要先执行子命令获取输出再执行外层命令时,应该使用的是$()或者包裹子命令.
echo "my_Path=${pwd}"这样的写法会把 pwd 当成一个变量处理.

进而#5,#6,#7也不会得到想要的结果.但是在这个过程里,我却误打误撞的明白了转义字符和-n这个命令参数的作用.

该转义时再转义

‘{}’并不需要转义,因为在这里并不是特殊字符.在man bash中的’’’metacharacter’’’ 和’’’control operator’’’中并没有这个符号.

-n 和 转义字符搭配

-n 这个参数的作用就是激活转义字符.

双引号和单引号的区别

‘’(单引号):又叫硬转义,其内部所有的shell 元字符、通配符都会被关掉。注意,硬转义中不允许出现’(单引号)。
“”(双引号):又叫软转义,其内部只允许出现特定的shell 元字符:$用于参数代换 `用于命令代替
(反斜杠):又叫转义,去除其后紧跟的元字符或通配符的特殊意义。

man bash 英文解释如下:

There are three quoting mechanisms: the escape character, single quotes, and double quotes.

正确的方法是…

我们回到这个语句本身,目的是通过 echo 把希望输出的内容原样写入某一个文件,这个时候,用单引号是最合适不过了.

1
2
echo 'my_path=$(pwd)' > test
echo 'echo $my_path' >> test

完美的完成任务~

Reference

linux - difference between ${} and $() in shell script - Super User

Linux Shell 通配符、元字符、转义符使用实例介绍 - 程默 - 博客园

ChangeLog

180720 新建
180725 更新,发布