shell学习三十八天----运行顺序和eval
运行顺序和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的更多相关文章
- shell学习五十八天----/proc文件系统
/proc文件系统 前言:linux中的/proc文件系统,由一组文件夹和文件组成,挂载(mount)与/proc文件夹下. /proc文件系统是一种虚拟文件系统,以文件系统文件夹和文件形式,提供一个 ...
- shell学习三十七天----引用
引用 案例,假设我想输出一个星号(*),使用echo怎样做? echo * 这是肯定不行的,须要将*转移,即:echo \* 这样就引出了引用的概念.所为引用,是用来防止shell将某些你想要的东西解 ...
- python学习三十八天常用内置函数分类汇总
python给我们提供丰富的内置函数,不用去写函数体,直接调用就可以运行,很方便快速给我提供开发所需要的函数. 1,查内存地址 id() 变量的内存地址 id() 2,输入输出 input() pr ...
- linux shell学习三
Shell for循环 Shell for循环的语法如下所示 for 变量 in 列表 do command1 command2 ... commandN done 举例: ..} do echo $ ...
- Struts2学习三----------Action搜索顺序
© 版权声明:本文为博主原创文章,转载请注明出处 Struts2的Action的搜索顺序 http://localhost:8080/path1/path2/student.action 1)判断pa ...
- shell学习三十四天----printf详解
http://blog.csdn.net/shanyongxu/article/details/46744055
- shell学习四十八天----文件校验和匹配
文件校验和匹配 要是你怀疑可能有非常多文件具有同样的内文,而是用cmp或diff进行比較全部横队的比較,导致所花费的时间会随着文件数目增长成次方的增长. 这是能够使用file checksum(文件校 ...
- PHP语言学习之php-fpm 三种运行模式
本文主要向大家介绍了PHP语言学习之php-fpm 三种运行模式,通过具体的内容向大家展示,希望对大家学习php语言有所帮助. php-fpm配置 配置文件:php-fpm.conf 开启慢日志功能的 ...
- Shell学习之环境变量配置文件(三)
Shell学习之环境变量配置文件 目录 环境变量配置文件简介 环境变量配置文件作用 其他配置文件和登录信息 环境变量配置文件简介 环境变量配置文件简介 环境变量配置文件中主要是定义对系统操作环境生效的 ...
随机推荐
- highcharts 坐标轴 数值 格式化
以Y轴为示例: yAxis: { min: 0, gridLineColor: '#ececee', gridLineWidth: 1, lineColor: '#ececee', lineWidth ...
- python求pi的方法
来自 #_*_ coding=utf-8 *_* ## {{{ http://code.activestate.com/recipes/578130/ (r5) def pi(places=10): ...
- 关于华为x1 7.0无法从eclipse发布的更新as发布的apk
目前只在华为x1 7.0手机上发现这个问题,坑大了. MediaPad 10 FHD 华为这款可以安装. HUAWEI G525-U00 华为这款也可以安装. 目前公司就这几款华为手机了. 原因是 在 ...
- Navicat Premium如何打开SQL文件.MDF和.LDF文件
相信大家再装SQL Server时都会遇到一件很头疼的事情--装完SQL server之后发现没有启动程序.没有经验的会以为SQL SERVER安装失败了于是选择重装.可是呵呵,重装了4,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 ...
- R快速创建个文件
cat("TITLE extra line", "2 3 5 7", "11 13 17", file="ex.data" ...
- Memcached 测试
Memcached set 命令用于将 value(数据值) 存储在指定的 key(键) 中. 如果set的key已经存在,该命令可以更新该key所对应的原来的数据,也就是实现更新的作用. 语法: s ...
- 用GDB命令PO(print-object)打印UIView的视图层级
UIView有一个私有方法: recursiveDescription 这个方法可以显示出当前视图的详细层级,可以在代码中直接调用,也可以在GDB中调用,在GDB中调用时需要借助另一个GDB命令:pr ...
- 读取properties属性文件——国际化
public class PropertiesInfo { /** * PropertiesInfo实例 */ private static PropertiesInfo pi = null; pri ...
- pandas drop_duplicates
函数 : DataFrame.drop_duplicates(subset=None, keep='first', inplace=False) 参数:这个drop_duplicate方法是对Data ...