运行顺序和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. list中依据map<String,Object>的某个值排序

    private void sort(List<Map<String, Object>> list) { Collections.sort(list, new Comparato ...

  2. 算法笔记_069:Floyd算法简单介绍(Java)

    目录 1 问题描述 2 解决方案 2.1 使用Floyd算法得到最短距离示例 2.2 具体编码   1 问题描述 何为Floyd算法? Floyd算法功能:给定一个加权连通图,求取从每一个顶点到其它所 ...

  3. 在LoadRunner中查找和替换字符串

    参考<Search & Replace function for LoadRunner>: http://ptfrontline.wordpress.com/2009/03/13/ ...

  4. hp-ux 集群,内存 小记

    -----查看hp 集群状态信息 # cmviewcl -v CLUSTER        STATUS       dbsvr          up               NODE      ...

  5. Android 6.0 超级简单的权限申请2 (Permission)

    代码地址如下:http://www.demodashi.com/demo/13506.html 写在前面 上次写了一个权限申请的例子Android 6.0 超级简单的权限申请 (Permission) ...

  6. golang test cannot find import

    1. 能够import别的项目的main package. 2. 可是引用别的项目main package的时候,须要首先删除~/bin/main_package_name(你所引用的报名),不然回报 ...

  7. oracle 存储过程 ,触发器练习

    /*以下代码是对emp表进行显示宽度设置 */col empno for 9999;col ename for a10;col job for a10;col mgr for 9999;col hir ...

  8. Linux命令-网络命令:mail

    root用户发送邮件 mail wangyunpeng 给wangyunpeng发送邮件,wangyunpeng不在线也可以收到发送的邮件 wangyunpeng用户接收邮件 mail 接收邮件 he ...

  9. Cocos2d-x开发---关于安卓打包所遇到的错误记录

         非常久都没有在安卓打过包了.之前的项目因为某些问题没有考虑做安卓版本号,所以涉及到安卓打包的时候都是自己在折腾.      这段时间离职了,空余时间就有非常多了.所以我能够折腾点事了.想起来 ...

  10. MYSQL手工注入某日本网站

    作者:ice   团队:www.anying.org 转载必须注明. E-mail:1c30day@gmail.com 经过一天的辛苦劳动下班了,实在无聊,QQ上的基友基本都挂机睡觉了.找点乐子打发时 ...