• 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,比如iffor.在这里不是,所以命令行不变继续运行.

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

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

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

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

    5.变量展开:token23都被改动.产生:

    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”,在此阶段被切分为两个单词:ab.同样方式也应用于命令替换$(echo cmd subst)的结果上.先前的token3变成了token34.先前的token4则成了token56.结果:

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

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

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

    echo /tmp/x/$f1 /tmp/x/$f2 a b cmd subst 5 

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

    10.这时,shell已经准备好了要运行最后的命令了,他会去寻找echo.正好ksh93bashecho都内建到shell中了

    11.shell实际运行命令.首先运行>outI/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的执行环境中保留下来.

  • 相关阅读:
    Lambda
    Guava
    创建数据库时报错 'str' object has no attribute 'decode'
    服务器并发测试(jmeter)
    Mosquitto 创建用户自动输入密码
    menuconfig 语法与用法
    Django操作mongodb
    mqtt mosquitto 安装与使用
    python 使用mongodb数据库
    djangorestframework token 认证
  • 原文地址:https://www.cnblogs.com/wzzkaifa/p/6781401.html
Copyright © 2020-2023  润新知