运行顺序和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. highcharts 坐标轴 数值 格式化

    以Y轴为示例: yAxis: { min: 0, gridLineColor: '#ececee', gridLineWidth: 1, lineColor: '#ececee', lineWidth ...

  2. python求pi的方法

    来自 #_*_ coding=utf-8 *_* ## {{{ http://code.activestate.com/recipes/578130/ (r5) def pi(places=10): ...

  3. 关于华为x1 7.0无法从eclipse发布的更新as发布的apk

    目前只在华为x1 7.0手机上发现这个问题,坑大了. MediaPad 10 FHD 华为这款可以安装. HUAWEI G525-U00 华为这款也可以安装. 目前公司就这几款华为手机了. 原因是 在 ...

  4. Navicat Premium如何打开SQL文件.MDF和.LDF文件

    相信大家再装SQL Server时都会遇到一件很头疼的事情--装完SQL server之后发现没有启动程序.没有经验的会以为SQL SERVER安装失败了于是选择重装.可是呵呵,重装了4,5次还是一样 ...

  5. Hibernate 使用log4j输出日志

      jar包不能少:F:\jars\slf4j-api-1.7.5.jar   F:\strutsWsold\slf4j-1.7.5\slf4j-1.7.5\slf4j-log4j12-1.7.5.j ...

  6. R快速创建个文件

    cat("TITLE extra line", "2 3 5 7", "11 13 17", file="ex.data" ...

  7. Memcached 测试

    Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用. 语法: s ...

  8. 用GDB命令PO(print-object)打印UIView的视图层级

    UIView有一个私有方法: recursiveDescription 这个方法可以显示出当前视图的详细层级,可以在代码中直接调用,也可以在GDB中调用,在GDB中调用时需要借助另一个GDB命令:pr ...

  9. 读取properties属性文件——国际化

    public class PropertiesInfo { /** * PropertiesInfo实例 */ private static PropertiesInfo pi = null; pri ...

  10. pandas drop_duplicates

    函数 : DataFrame.drop_duplicates(subset=None, keep='first', inplace=False) 参数:这个drop_duplicate方法是对Data ...