第四篇
了解Shell 命令执行流程图

  {网中人大哥推荐参考Learning the Bash Shell, 2nd Edition,第 178页;中文版229页}

Shell 从标准输入或脚本中读取的每一行称为管道(pipeline);它包含了一个或多个命令(command),这些命令被一个或多个管道字符(|)隔开

事实上还有很多特殊符号可用来分隔单个的命令:分号(;)、管道(|)、&、逻辑AND (&&),还有逻辑OR (||)。对于每一个读取的管道,Shell都会将命令分割,为管道设置I/O,并且对每一个命令依次执行下面的操作:


整个步骤顺序如上图所示,看起来有些复杂。
当命令行被处理时,每一个步骤都是在Shell的内存里发生的;Shell不会真的把每个步骤的发生显示给你看。
所以,你可以假想这事我们偷窥Shell内存里的情况,从而知道每个阶段的命令行是如何被转换的。
我们从这个例子开始说:

$ mkdir /tmp/x 建立临时性目录
$ cd /tmp/x 切换到该目录
$ touch f1 f2 建立文件
$ f=f y="a b" 赋值两个变量
$ echo ~+/${f}[12] $y $(echo cmd subst ) $(( 3 + 2 )) > out 将结果重定向到out

  

上述的执行步骤概要如下:

1.命令一开始回根据Shell语法而分割为token。最重要的一点是:I/O重定向 >out 在这里是被识别的,并存储供稍后使用。流程继续处理下面这行,其中每个token的范围显示于命令下面的行上:

echo  ~+/${f}[12]    $y   $(echo cmd subst)   $((3 + 2))
| 1 | |------ 2 ------| | 3 | |--------- 4 --------| |----5-----|

2.检查第一个单词(echo)是否为关键字,例如 if 或 for 。这里不是,所以命令行不变继续处理。
3.检查第一个单词(echo)是否为别名。这里不是。所以命令行不变,继续处理。
4.扫描所以单词是否需要波浪号展开。在本例中,~+ 为ksh93 与 bash 的扩展,等同于$PWD,也就是当前的目录。token 2将被修改,处理如下:

echo /tmp/x/${f}[12] $y   $(echo cmd subst)   $((3 + 2))
| 1 | |------- 2 -------| |3 | |-------- 4----------| |----5-----|

5.下一步是变量展开:token 2 与 3 都被修改。这样会产生:

echo /tmp/x/${f}[12] a b   $(echo cmd subst)   $((3 + 2))
| 1 | |------- 2 -------| | 3 | |-------- 4----------| |----5-----|

6.再来要处理的是命令替换。注意,这里可用递归应用列表里的所有步骤!在这里,命令替换修改了 token 4:

echo /tmp/x/${f}[12] a b  cmd subst   $((3 + 2))
| 1 | |------- 2 -------| | 3 | |--- 4 ----| |----5-----|

7.现在执行算数替换。修改的是 token 5,结果:

echo /tmp/x/${f}[12]    a b   cmd subst   5
| 1 | |-------- 2 --------| | 3 | |--- 4 ----| |5|

8.前面所有的展开产生的结果,都将再一次被扫描,看看是否有 $IFS 字符。如果有,则他们是作为分隔符(separator),产生额外的单词,例如,两个字符$y 原来是组成一个单词,单展开式“a- 空格-b”,在此阶段被切分为两个单词:a 与 b。相同方式也应用于命令$(echo cmd subst)的结果上。先前的 token 3 变成了 token 3 与
token 4.先前的 token 4则成了 token 5 与 token 6。结果:

echo /tmp/x/${f}[12]   a b  cmd subst   5
| 1 | |-------- 2 --------| 3 4 |-5-| |- 6 -| 7 |

9.最后的替换阶段是通配符展开。token 2 变成了 token 2 与 token 3:

echo  /tmp/x/$f1   /tmp/x/$f2  a b  cmd  subst  5
| 1 | |----- 2 -----| |---- 3 ----| 4 5 |-6-| |- 7 -| 8 |

10.这时,Shell已经准备好了要执行最后的命令了。它会去寻找 echo。正好 ksh93 与 bash 的 echo 都内建到Shell 中了。

11.Shell实际执行命令。首先执行 > out 的 I/O重定向,再调用内部的 echo 版本,显示最后的参数。

最后的结果:

$cat out
/tmp/x/f1 /tmp/x/f2 a b cmd subst 5

  

参照linux公社:http://www.jb51.net/article/34326.htm

shell第四篇(上)的更多相关文章

  1. 【转】Shell编程基础篇-上

    [转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...

  2. shell第四篇(下)

    摘自王垠的:Unix的缺陷 我想通过这篇文章解释一下我对 Unix 哲学本质的理解.我虽然指出 Unix 的一个设计问题,但目的并不是打击人们对 Unix 的兴趣.虽然 Unix 在基础概念上有一个挺 ...

  3. Shell编程基础篇-上

    1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shell脚 ...

  4. JDownload: 一款可以从网络上下载文件的小程序第四篇(整体架构描述)

    一 前言 时间过得真快,距离本系列博客第一篇的发布已经过去9个月了,本文是该系列的第四篇博客,将对JDownload做一个整体的描述与介绍.恩,先让笔者把记忆拉回到2017年年初,那会笔者在看Unix ...

  5. [转帖]虚拟内存探究 -- 第四篇:malloc, heap & the program break

    虚拟内存探究 -- 第四篇:malloc, heap & the program break http://blog.coderhuo.tech/2017/10/19/Virtual_Memo ...

  6. 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)

    从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...

  7. 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)

    目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...

  8. 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)

    解剖SQLSERVER 第十四篇    Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...

  9. 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)

    解剖SQLSERVER 第四篇  OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...

随机推荐

  1. 学习总结:工程管理与makefile

    工程管理与makefile 一.为什么需要makefile和make 一个工程中的源文件可能很多,按照类型.功能.模块分别放在若干个目录中,为了有效地管理软件工程,更高效地编译整个工程,需要用到mak ...

  2. 解决CentOS7安装Tomcat不能被外部访问的问题

    在CentOS7安装了Tomcat,在服务器内部使用火狐浏览器通过localhost:8080是可以访问的,但是不能被外部访问,主要原因是因为防火墙的存在,导致端口不能被访问.CentOS是使用fir ...

  3. [51nod1297]管理二叉树

    一个初始为空的二叉搜索树T,以及1到N的一个排列P: {a1, a2, ..., aN}.我们向这个二叉搜索树T添加这些数,从a1开始, 接下来是 a2, ..., 以aN结束.在每一个添加操作后,输 ...

  4. HDU 1241 DFS

    Oil Deposits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Tota ...

  5. BOX

    题目连接:http://acm.tju.edu.cn/toj/showp2392.html2392.   Box Time Limit: 1.0 Seconds   Memory Limit: 655 ...

  6. 两句话概括cmd和amd的区别

    === | === | === | ===AMD | 速度快 | 会浪费资源 | 预先加载所有的依赖,直到使用的时候才执行=== | === | === | ===CMD | 只有真正需要才加载依赖 ...

  7. nth-child()选择器小结

    之前也用到过nth-child,只是当时理解的不够透彻.今天回过头去看这个知识点时,发现了一个易错点. 浏览器支持情况: 所有主流浏览器都支持nth-child()选择器,除了IE8及更早的版本. 下 ...

  8. {style}/index_article.htm {style}表示什么意思啊

    LS有点安全意识好不好.... 在你的后台系统设置有个"模板默认风格:________  cfg_df_style " 默认是default也就是 {style}=模板路径+模板默 ...

  9. Dede 删除文档同时文章中的图片的方法

    首先,在"/include"目录下建立"extend.func.php"文件. 然后,将以下内容保存在"extend.func.php"文件 ...

  10. CUDA与OpenGL互操作

    当处理较大数据量的时候,往往会用GPU进行运算,比如OpenGL或者CUDA.在实际的操作中,往往CUDA实现并行计算会比OpenGL更加方便,而OpenGL在进行后期渲染更具有优势.由于CUDA中的 ...