免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 6539 | 回复: 12

[学习共享] 关于echo和\的疑问 [复制链接]

论坛徽章:
0
发表于 2012-02-06 13:45 |显示全部楼层
本帖最后由 edsionte 于 2012-02-13 14:41 编辑

有如下的脚本:
$cat /tmp/test_echo.sh
#!/bin/bash

set -x
echo `echo \z`        #  z
echo `echo \\z`       #  z
echo `echo \\\z`      # \z
echo `echo \\\\z`     # \z
echo `echo \\\\\\z`   # \z
echo `echo \\\\\\\z`  # \\z

结果在bash下运行是:
$/tmp/test_echo.sh
++ echo z
+ echo z
z
++ echo z
+ echo z
z
++ echo '\z'
+ echo '\z'
\z
++ echo '\z'
+ echo '\z'
\z
++ echo '\z'
+ echo '\z'
\z
++ echo '\\z'
+ echo '\\z'
\\z

各位大侠,请问:

1.上述几条命令的内部echo是如何处理\的?

我知道这里用到了转义,但是不清楚具体如何转义的?

如果将上述的反引号换成$(),那么结果又如下(同在bash下):

++ echo z
+ echo z
z
++ echo '\z'
+ echo '\z'
\z
++ echo '\z'
+ echo '\z'
\z
++ echo '\\z'
+ echo '\\z'
\\z
++ echo '\\\z'
+ echo '\\\z'
\\\z
++ echo '\\\z'
+ echo '\\\z'
\\\z

2.反引号和$()为什么会在该例子中产生不同结果?

论坛徽章:
0
发表于 2012-02-07 21:22 |显示全部楼层
无人回复么。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
发表于 2012-02-11 13:58 |显示全部楼层
edsionte 发表于 2012-02-07 21:22
无人回复么。
先看看反引号内部的结果。
外面没有被引号引起来的backslash,\,符号在Bash当中是escape character,作用是保留了下一个字符的字面含义。注意,仅仅是\后的一个字符。作出这种解析的是Bash,而不是echo程序。
  1. $ echo \z
  2. z
  3. # 这里好理解吧,\z被Bash解析为z,然后echo就直接显示啦
  4. $ echo \\z
  5. \z
  6. # 上面的\\被Bash解释为\,而z就是z啦
  7. $ echo \\\z
  8. \z
  9. # 上面的\\被Bash解析为\,然后\z被解析为z,连起来就是\z啦
  10. $ echo \\\\z
  11. \\z
  12. # 上面的\\被Bash解析为\,然后后面两个\\被解析为\,然后就是z,然后连起来就是\\z
  13. $ echo \\\\\\z
  14. \\\z
  15. # 情况类似,\和它后面的一个字符组合,保留它后面一个字符的字面意义,得到\\\,然后最后是z,最后连起来就是\\\z
  16. $ echo \\\\\\\z
  17. \\\z
  18. # 上面的也是,\\\\\\被Bash解释为\\\,然后是\z被解释为z,最后连起来就是\\\z,然后交给echo就直接显示啦,
  19. # 上面的所有echo显示都会在后面追加一个换行的
复制代码
上面的只是让你知道没有被引号(单引号,双引号,反引号)引起来的backslash在Bash当中的解析。如果是被引号(双引号和反引号,除了单引号,单引号里面是什么就是什么,Bash不会重新过滤)引起来的backslash,
在Bash当中是这么解析的,如果backslash后面的一个字符是dollar, backtick, double quote, backslash or newline,这个前导的backslash将被Bash移除(从输入流当中就处理了),而dollar,backtick,double quote,backslash or newline将保留它们本身的含义。
再来看看你的例子,外层echo显示需要获取输入显示的内容,由于你的例子里面有反引号,所以Bash先在input stream当中进行过滤一遍。这里是你的输入:
  1. echo `echo \z`        #  z
  2. echo `echo \\z`       #  z
  3. echo `echo \\\z`      # \z
  4. echo `echo \\\\z`     # \z
  5. echo `echo \\\\\\z`   # \z
  6. echo `echo \\\\\\\z`  # \\z
复制代码
过滤后
  1. echo `echo \z`   
  2. # 上面的前导\没有移除,因为z不属于dollar, backtick, double quote, backslash or newline当中
  3. echo `echo \z`   
  4. # \\当中的前导\被移除
  5. echo `echo \\z`   
  6. # \\当中的前导被移除,\z不变
  7. echo `echo \\z`   
  8. # \\\\两个前导被移除,得到\\,z就是z,连接起来是\\z
  9. echo `echo \\\z`
  10. # 移除三个前导,得到\\\z
  11. echo `echo \\\\z`
  12. # 移除三个前导,得到\\\,然后后面是\z,不变,连起来是\\\\z
复制代码
执行反引号里面的echo,这里按照帖子开头说的escape character进行解析,然后就是你要的结果了。
  1. $ echo \z
  2. z
  3. $ echo \z
  4. z
  5. $ echo \\z
  6. \z
  7. $ echo \\z
  8. \z
  9. $ echo \\\z
  10. \z
  11. $ echo \\\\z
  12. \\z
复制代码
主要还是要分清楚escape character以及引号当中的backslash的区别,这个就容易理解了。escape character一律对后面的字符保留字面意思,而引号(除单引号)当中的backslash碰到后面是
dollar, backtick, double quote, backslash or newline五种字符时,Bash会把前导的backslash移除,后面的那个字符保留原本含义。

上面部分是一些个人理解,不对之处,还望指正。


论坛徽章:
0
发表于 2012-02-13 11:31 |显示全部楼层
回复 2# edsionte


    谢谢L_kernel,好几天的疑问终于明白了。

论坛徽章:
0
发表于 2012-02-13 11:33 |显示全部楼层
回复 3# L_kernel


    我再问一下,像“如果是被引号(双引号和反引号,除了单引号,单引号里面是什么就是什么,Bash不会重新过滤)引起来的backslash,
在Bash当中是这么解析的,如果backslash后面的一个字符是dollar, backtick, double quote, backslash or newline,这个前导的backslash将被Bash移除(从输入流当中就处理了),而dollar,backtick,double quote,backslash or newline将保留它们本身的含义。”这种规则在哪里可以看到? 谢谢。

论坛徽章:
145
技术图书徽章
日期:2013-10-01 15:32:13戌狗
日期:2013-10-25 13:31:35金牛座
日期:2013-11-04 16:22:07子鼠
日期:2013-11-18 18:48:57白羊座
日期:2013-11-29 10:09:11狮子座
日期:2013-12-12 09:57:42白羊座
日期:2013-12-24 16:24:46辰龙
日期:2014-01-08 15:26:12技术图书徽章
日期:2014-01-17 13:24:40巳蛇
日期:2014-02-18 14:32:59未羊
日期:2014-02-20 14:12:13白羊座
日期:2014-02-26 12:06:59
发表于 2012-02-13 12:11 |显示全部楼层
回复 5# edsionte

shell 十三問?
4) " "(雙引號) 與 ' '(單引號)差在哪?   

论坛徽章:
13
15-16赛季CBA联赛之同曦
日期:2016-01-28 19:52:032015亚冠之北京国安
日期:2015-10-07 14:28:19NBA常规赛纪念章
日期:2015-05-04 22:32:03处女座
日期:2015-01-15 19:45:44卯兔
日期:2014-10-28 16:17:14白羊座
日期:2014-05-24 15:10:46寅虎
日期:2014-05-10 09:50:35白羊座
日期:2014-03-12 20:52:17午马
日期:2014-03-01 08:37:27射手座
日期:2014-02-19 19:26:54子鼠
日期:2013-11-30 09:03:56狮子座
日期:2013-09-08 08:37:52
发表于 2012-07-05 09:37 |显示全部楼层
不错的总结 O_o

论坛徽章:
21
白羊座
日期:2013-08-23 15:49:17金牛座
日期:2013-10-08 17:00:03处女座
日期:2013-10-12 11:54:11CU十二周年纪念徽章
日期:2013-10-24 15:41:34午马
日期:2013-11-27 14:07:21巨蟹座
日期:2013-12-04 10:56:03水瓶座
日期:2013-12-04 15:58:00亥猪
日期:2014-05-24 16:02:3115-16赛季CBA联赛之辽宁
日期:2016-11-07 13:52:53戌狗
日期:2013-08-23 16:15:31白羊座
日期:2013-08-24 21:59:24巨蟹座
日期:2013-08-25 16:34:24
发表于 2012-07-05 11:48 |显示全部楼层
学习了.  O-o

论坛徽章:
0
发表于 2012-07-05 11:57 |显示全部楼层
这东西好像不同系统,不同的shell效果还不太一样,用的时候不行就多加几个都试试就好了;

--不要bs我不求甚解

论坛徽章:
0
发表于 2012-07-05 17:40 |显示全部楼层
不错,学习了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP