运行顺序和eval

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

其实嗨哟非常多特殊符号可用来切割单个的命令:分号(;),管道(|),&,逻辑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      #忙碌的命令

上述命令的运行步骤:

1.命令一開始会依据shell语法而切割为token.最重要的一点是:I/O重定向>out在这里是被识别的,并存储供稍后使用.流程继续处理以下这行,当中每一个token的范围显示于命令下方的行上:

echo ~+/${f}[12] $y $(echo cmd subst) $((3 + 2))

| 1 | |----- 2 ----| |3 | |-------- 4----------| |----5-----|

2.坚持第一个单词(echo)是否为keyword,比如if或for.在这里不是,所以命令行不变继续运行.

3.坚持第一个单词(依旧是echo)是否为别名.这里不是,所以命令行不变继续处理.

4.扫描全部单词是否须要波浪号展开.在这里~+等同于$PWD,也就是当前文件夹.token2将被改动,处理继续例如以下:

echo /tmp/x/${f}[12] $y $(echo cmd subst) $((3 + 2))

| 1 | |------- 2 -------| |3 | |-------- 4----------| |----5-----|

5.变量展开:token2与3都被改动.产生:

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

| 1 | |------- 2 -------| | 3 | |-------- 4----------| |----5-----|

6.处理命令替换.注意,这里可递归引用列表里的全部步骤!在此例中,由于我们要试图让全部的东西easy理解,因此命令改动了token4,结果:

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

| 1 | |------- 2 -------| | 3 | |--- 4 ----| |----5-----|

7.运行算术替换 .改动token5,结果:

echo /tmp/x/${f}[12] a b cmd subst 5

| 1 | |------- 2 -------| | 3 | |--- 4 ----| |5|

8.前面全部的展开产生的结果,都将再一次被扫描,看看是否有$IFS字符.假设有,则他们是作为分隔符,产生额外的单词.比如,两个字符$y原来是组成一个单词,但展开式”a空格b”,在此阶段被切分为两个单词:a与b.同样方式也应用于命令替换$(echo cmd subst)的结果上.先前的token3变成了token3与4.先前的token4则成了token5与6.结果:

echo /tmp/x/${f}[12] a b cmd subst 5

| 1 | |------- 2 -------| 3 4 |-5-| |- 6 -| 7

9.通配符展开.token2变成了token2与token3:

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

eval语句

shell中的eval这个命令非常奇妙,他能把字符串当做命令来运行.PS:这个字符串必须是可运行的bash命令才干够.

案例:

eval “ls” #输出当前文件夹的全部文件

语法: eval [參数]

补充说明:eval可读取一连串的參数,然后再依慘呼本身的特性来运行.

參数:不限数目,彼此之间用分号隔开.

案例:我有一个文件test.txt

命令:cat test.txt

输出:hello world

命令:myfile="cat test.txt"

命令:echo $myfile

输出:cat test.txt

命令:eval $myfile

输出:hello world

从eval $myfile这条命令能够看出,eval进行了变量替换,将字符串中属于bash的命令运行了.

把拼接起来的字符串当作命令运行,这就是eval的奇妙之处.

subShell与代码块

subShell是一群被括在圆括号中的命令,这些命令会在另外的进程中运行.当你须要让一小组的命令在不同的文件夹下运行时,这样的方式能够让你不必改动主脚本的文件夹,直接处理这样的情况.

比如:tar -cf -.| (cd /tmp;tar -xpf -)

左边的tar命令会产生当前文件夹的tar打包文件,将他传送给标准输出.这份打包文件会通过管道传递给走遍的subShell里的命令.开头的cd命令会先切换到新文件夹,也就是让大宝文件在此文件夹下解开.然后,走遍的tar将从打包文件里解开文件.注意,运行此管道的shell(或脚本)并未更改他的文件夹.

代码块概念上与subShell雷同,仅仅只是他不会建立新的进程.代码块里的命令以花括号({})括起来,且对主脚本的状态会造成影响(比如他的当前文件夹).一般来说,花括号被视为shellkeyword,意即他们仅仅有出如今命令的第一个符号时会被识别.实际上:这表示你必须将结束花括号放置在换行字符或分号之后.比如:

cd /home/directory||{

echo could not change to /home/directory!>&2

echo you lose !>&2

exit1

}

IO重定向也能够套用subShell与代码块里.在该情况下,全部的命令会从重定向来源读取它们的输入或传送他们的输出.

subShell与代码块

结构

定界符

认可的位置

另外的进程

SubShell

()

行上的不论什么位置

代码块

{}

在换行字符,分号或keyword之后

注意:代码块里的exit会终止整个脚本.

我们通常在shell中执行一个脚本仅仅须要简单的调用./[script_name]就可以,这样的方式下,shell会启动一个子进程来执行该脚本,称为subShell,当subShell执行完毕,子进程结束.父进程的环境不会有不论什么改变.

案例:bash代码

#!/bin/bash

cd /var/cache

testname="fine"

分别在shell中执行

1.  ./test.sh;echo $testname  会发现还是位于原来的文件夹中,$testname的值书粗话为null.

2. source ./test.sh;echo $testname这里就不一样了,如今你位于/var/cache中,$testname的值也变成了fine

用source命令来执行脚本,不会产生子进程,脚本在shell的进程空间中执行,所以执行重定义的变量,执行的操作,都会在shell的执行环境中保留下来.

shell学习三十八天----运行顺序和eval的更多相关文章

  1. shell学习五十八天----/proc文件系统

    /proc文件系统 前言:linux中的/proc文件系统,由一组文件夹和文件组成,挂载(mount)与/proc文件夹下. /proc文件系统是一种虚拟文件系统,以文件系统文件夹和文件形式,提供一个 ...

  2. shell学习三十七天----引用

    引用 案例,假设我想输出一个星号(*),使用echo怎样做? echo * 这是肯定不行的,须要将*转移,即:echo \* 这样就引出了引用的概念.所为引用,是用来防止shell将某些你想要的东西解 ...

  3. python学习三十八天常用内置函数分类汇总

    python给我们提供丰富的内置函数,不用去写函数体,直接调用就可以运行,很方便快速给我提供开发所需要的函数. 1,查内存地址 id() 变量的内存地址 id() 2,输入输出 input()  pr ...

  4. linux shell学习三

    Shell for循环 Shell for循环的语法如下所示 for 变量 in 列表 do command1 command2 ... commandN done 举例: ..} do echo $ ...

  5. Struts2学习三----------Action搜索顺序

    © 版权声明:本文为博主原创文章,转载请注明出处 Struts2的Action的搜索顺序 http://localhost:8080/path1/path2/student.action 1)判断pa ...

  6. shell学习三十四天----printf详解

    http://blog.csdn.net/shanyongxu/article/details/46744055

  7. shell学习四十八天----文件校验和匹配

    文件校验和匹配 要是你怀疑可能有非常多文件具有同样的内文,而是用cmp或diff进行比較全部横队的比較,导致所花费的时间会随着文件数目增长成次方的增长. 这是能够使用file checksum(文件校 ...

  8. PHP语言学习之php-fpm 三种运行模式

    本文主要向大家介绍了PHP语言学习之php-fpm 三种运行模式,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. php-fpm配置 配置文件:php-fpm.conf 开启慢日志功能的 ...

  9. Shell学习之环境变量配置文件(三)

    Shell学习之环境变量配置文件 目录 环境变量配置文件简介 环境变量配置文件作用 其他配置文件和登录信息 环境变量配置文件简介 环境变量配置文件简介 环境变量配置文件中主要是定义对系统操作环境生效的 ...

随机推荐

  1. Android开发 之 我的jar包引用方法

    1.在工程上名上右键->Build Path ->Configure Build Path 2.在Libraries选项卡中,选择右侧的Add External JARs,然后选择要导入的 ...

  2. silverlight客户端保存文件乱码问题

    最近做一个项目,有一个需求是这样的:服务端从数据库里获得数据,客户端保存为Excel文件 最初解决方案:服务端获得数据,通过ExcelPackage,Convert.ToBase64String将by ...

  3. webDriver API——第11部分Remote WebDriver

    The WebDriver implementation. class selenium.webdriver.remote.webdriver.WebDriver(command_executor=' ...

  4. Visual studio之C#的一些常见问题

    背景 要写一个APP,APP通过串口控制下位机,在此记录C#的一些常用控件的使用办法. 正文 单击button控件,执行对应操作. 选择要操作的button控件,在属性栏内点击类似闪电标志一样的事件, ...

  5. UIScrollerView当前显示3张图

    代码地址如下:http://www.demodashi.com/demo/11173.html WSLScrollView 功能描述:这是在继承UIView的基础上利用UIScrollerView进行 ...

  6. 关于new与=号创建对象的区别

    (1)先定义一个名为str的对String类的对象引用变量:String str: (2)[在[栈]中查找有没有存放值为"abc"的地址,如果没有,则开辟一个存放字面值为" ...

  7. ss - float浮动模块的高度问题 解决方案

    当一个Div中的子元素都是浮动元素时,该div是没有高度的.通常会带来很多困扰,解决方案如下: 低版本统配兼容: overflow: hidden; 下面是不支持低配浏览器,而且似乎该效果对 P 标签 ...

  8. Atitit .h5文件上传 v3

    Atitit .h5文件上传 v3 1. 上传原理1 2. V3版新特性1 3. Html1 4. Js2 5. uploadV2.js2 6. upServlet & FileUploadS ...

  9. HashMap 内部原理

    HashMap 内部实现 通过名字便可知道的是,HashMap 的原理就是散列.HashMap内部维护一个 Buckets 数组.每一个 Bucket 封装为一个 Entry<K, V> ...

  10. Cookie的新增,设置与清除

    addCookieBtn.addEventListener('click',function () { document.cookie='imooc=www.imooc.com;expires=201 ...