shell第四篇(上)
第四篇
了解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第四篇(上)的更多相关文章
- 【转】Shell编程基础篇-上
[转]Shell编程基础篇-上 1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应 ...
- shell第四篇(下)
摘自王垠的:Unix的缺陷 我想通过这篇文章解释一下我对 Unix 哲学本质的理解.我虽然指出 Unix 的一个设计问题,但目的并不是打击人们对 Unix 的兴趣.虽然 Unix 在基础概念上有一个挺 ...
- Shell编程基础篇-上
1.1 前言 1.1.1 为什么学Shell Shell脚本语言是实现Linux/UNIX系统管理及自动化运维所必备的重要工具, Linux/UNIX系统的底层及基础应用软件的核心大都涉及Shell脚 ...
- JDownload: 一款可以从网络上下载文件的小程序第四篇(整体架构描述)
一 前言 时间过得真快,距离本系列博客第一篇的发布已经过去9个月了,本文是该系列的第四篇博客,将对JDownload做一个整体的描述与介绍.恩,先让笔者把记忆拉回到2017年年初,那会笔者在看Unix ...
- [转帖]虚拟内存探究 -- 第四篇:malloc, heap & the program break
虚拟内存探究 -- 第四篇:malloc, heap & the program break http://blog.coderhuo.tech/2017/10/19/Virtual_Memo ...
- 从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点)
从0开始搭建SQL Server AlwaysOn 第四篇(配置异地机房节点) 第一篇http://www.cnblogs.com/lyhabc/p/4678330.html第二篇http://www ...
- 【第四篇】ASP.NET MVC快速入门之完整示例(MVC5+EF6)
目录 [第一篇]ASP.NET MVC快速入门之数据库操作(MVC5+EF6) [第二篇]ASP.NET MVC快速入门之数据注解(MVC5+EF6) [第三篇]ASP.NET MVC快速入门之安全策 ...
- 解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译)
解剖SQLSERVER 第十四篇 Vardecimals 存储格式揭秘(译) http://improve.dk/how-are-vardecimals-stored/ 在这篇文章,我将深入研究 ...
- 解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译)
解剖SQLSERVER 第四篇 OrcaMDF里对dates类型数据的解析(译) http://improve.dk/parsing-dates-in-orcamdf/ 在SQLSERVER里面有几 ...
随机推荐
- 安装配置Oracle 12c RAC
http://www.lab128.com/rac12_installation_using_vb/article_text.html
- LevelDB的源码阅读(三) Put操作
在Linux上leveldb的安装和使用中我们写了这么一段测试代码,内容以及输出结果如下: #include <iostream> #include <string> #inc ...
- Zabbix实战-简易教程--拓扑图(Maps)
一.拓扑图(Maps) 二话不说,有图有真相,先看看效果,再详细讲解配置过程: 图1:全国网络质量图 图2 核心机房网络质量图 二.详细配置 1.添加 map 选择 系统管理-->基础配置-- ...
- Erlang/OTP设计原则(文档翻译)
http://erlang.org/doc/design_principles/des_princ.html 图和代码皆源自以上链接中Erlang官方文档,翻译时的版本为20.1. 这个设计原则,其实 ...
- reduce 方法 (Array) (JavaScript)
对数组中的所有元素调用指定的回调函数.该回调函数的返回值为累积结果,并且此返回值在下一次调用该回调函数时作为参数提供. 语法 array1.reduce(callbackfn[, in ...
- python实现求最长子串长度
给定一个字符串,求它最长的回文子串长度,例如输入字符串'35534321',它的最长回文子串是'3553',所以返回4. 最容易想到的办法是枚举出所有的子串,然后一一判断是否为回文串,返回最长的回文子 ...
- BZOJ 3098: Hash Killer II(新生必做的水题)
3098: Hash Killer II Time Limit: 5 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1555 Solved: ...
- Result Maps collection does not contain value for com.man.impet.dao.OrderBeanMapper.map
由于mapper.xml中resultMap = "map" 改为 resultType="map"即可,折腾了一下午
- sublime汉化教程
转自: http://www.cnblogs.com/marsggbo/p/6622960.html 如何给sublime text3安装汉化包?so easy 哦 这是我本人亲身测试过的,肯定有效, ...
- ThinkPHP 下载、导入、导出功能的设计与实现
下载: 1.引入命名空间: use Org\Net\Http; 2.在入口文件中设置根目录: //定义根目录的绝对地址 define('ROOT',str_replace("\\" ...