Linux:执行命令的命令eval与Bash解析命令的方式

2024-03-22 21:12

本文主要是介绍Linux:执行命令的命令eval与Bash解析命令的方式,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

相关阅读

Linuxicon-default.png?t=N7T8https://blog.csdn.net/weixin_45791458/category_12234591.html?spm=1001.2014.3001.5482


        eval命令用于接收参数,并将这些参数作为一行命令执行,这也许会使人困惑,为什么我不能直接执行命令而需要使用eval命令间接执行呢?本文将解开这些疑惑。

        eval命令的语法如下所示,可以看到它非常简单。

用法
eval [args]
参数
args 用于组成一行命令的参数

        下面简单了解一下Bash解析一行命令的过程,这有利于之后学习eval命令。

1、Bash首先根据在考虑双引号、单引号、转义符的前提下,根据空格、制表符、换行符、命令结束符(;)、管道命令符(|)、重定向命令符(>,<)、左右括号、后台运行符(&)等将一行命令拆成多个命令和每个命令相应的token。

2、随后Bash对每个命令的第一个token进行别名替换检查,如该token是一个别名,则会进行替换。

3、之后Bash会对第一条命令(注意不是全部命令),依次进行大括号替换(Brace Expansion)、波浪号替换(Tilde Expansion)、变量替换(Parameter Expansion)、命令替换(Command Expansion)、算数替换(Arithmetic Expansion)、Token重解析(Word Splitting)和路径名替换(Pathname Expansion)。

4、最后才是执行命令,即将第一个token当做命令名,其他token作为参数和选项。

        所以,下面这种执行命令的方式是可行的,即使其有点奇怪。

[***@EDA ~]$ command='echo Hello' #这里需要使用双引号或单引号,这样等号后面的字符串才会被解析为一个token
[***@EDA ~]$ $command #其经历了变量替换、Token重解析后变成了两个token:echo和hello,所以命令名为echo,参数为Hello
Hello
[***@EDA ~]$ 'echo Hello' #直接使用字符串是不行的,因为其会被解析为一个token,直到最后被当做一个命令名
bash: echo Hello: command not found... #报错,无法找到命令

        但是直接使用变量替换去执行命令也是有问题的,它可行完全是因为Token重解析,如果此时变量的字符串代表两条命令,则会出现问题,如下所示。

[***@EDA ~]$ command='echo Hello;echo World'  #本意是想输出Hello World
[***@EDA ~]$ $command
Hello;echo World   
#由于进行变量替换时已经是第3步了,无法再将一行命令解析为多个命令(第1步),
#此时的Token重解析将Hello;echo World整体作为了echo的参数

        但是如果使用eval命令就可以解决上面两个问题,因为它可以将其参数重新组织为一行命令,并重新经历上面所说的4步过程。

[***@EDA ~]$ eval 'echo Hello' 
#即使echo Hello作为一个token是eval命令的参数,
#但eval将这个字符串作为一行命令,所以其又会被解析成echo和Hello两个token并正确执行
Hello
[***@EDA ~]$ command='echo Hello;echo World'  #本意是想输出Hello World
[***@EDA ~]$ eval $command 
#首先进行变量替换,结果为eval echo Hello;echo World,Token重解析后它们成为eval命令的三个参数,
#即echo、Hello;echo和World,最后被组织成一行命令,并解析为两条命令,即echo Hello和echo World
Hello
World         

        一个变量替换的结果不会再进行变量替换,如下所示,但使用eval命令可以做到。

[***@EDA ~]$ a=1
[***@EDA ~]$ b='$a'  #这里使用单引号阻止变量替换
[***@EDA ~]$ echo $b
$a                   #结果不会进一步替换
[***@EDA ~]$ eval echo $b #首先$b进行变量替换变成$a,随后echo和$a作为eval的两个参数,被组织成一行命令,echo $a,并再次变量替换为echo 1,最后输出1
1

        最后建议谨慎使用eval命令,因为它能将传给他的参数作为命令执行,即使你可能不知道这个参数的具体值,这会导致安全性问题。

这篇关于Linux:执行命令的命令eval与Bash解析命令的方式的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/836201

相关文章

linux生产者,消费者问题

pthread_cond_wait() :用于阻塞当前线程,等待别的线程使用pthread_cond_signal()或pthread_cond_broadcast来唤醒它。 pthread_cond_wait() 必须与pthread_mutex 配套使用。pthread_cond_wait()函数一进入wait状态就会自动release mutex。当其他线程通过pthread

如何突破底层思维方式的牢笼

我始终认为,牛人和普通人的根本区别在于思维方式的不同,而非知识多少、阅历多少。 在这个世界上总有一帮神一样的人物存在。就像读到的那句话:“人类就像是一条历史长河中的鱼,只有某几条鱼跳出河面,看到世界的法则,但是却无法改变,当那几条鱼中有跳上岸,进化了,改变河道流向,那样才能改变法则。”  最近一段时间一直在不断寻在内心的东西,同时也在不断的去反省和否定自己的一些思维模式,尝试重

Linux 安装、配置Tomcat 的HTTPS

Linux 安装 、配置Tomcat的HTTPS 安装Tomcat 这里选择的是 tomcat 10.X ,需要Java 11及更高版本 Binary Distributions ->Core->选择 tar.gz包 下载、上传到内网服务器 /opt 目录tar -xzf 解压将解压的根目录改名为 tomat-10 并移动到 /opt 下, 形成个人习惯的路径 /opt/tomcat-10

RedHat运维-Linux文本操作基础-AWK进阶

你不用整理,跟着敲一遍,有个印象,然后把它保存到本地,以后要用再去看,如果有了新东西,你自个再添加。这是我参考牛客上的shell编程专项题,只不过换成了问答的方式而已。不用背,就算是我自己亲自敲,我现在好多也记不住。 1. 输出nowcoder.txt文件第5行的内容 2. 输出nowcoder.txt文件第6行的内容 3. 输出nowcoder.txt文件第7行的内容 4. 输出nowcode

【Linux进阶】UNIX体系结构分解——操作系统,内核,shell

1.什么是操作系统? 从严格意义上说,可将操作系统定义为一种软件,它控制计算机硬件资源,提供程序运行环境。我们通常将这种软件称为内核(kerel),因为它相对较小,而且位于环境的核心。  从广义上说,操作系统包括了内核和一些其他软件,这些软件使得计算机能够发挥作用,并使计算机具有自己的特生。这里所说的其他软件包括系统实用程序(system utility)、应用程序、shell以及公用函数库等

解析 XML 和 INI

XML 1.TinyXML库 TinyXML是一个C++的XML解析库  使用介绍: https://www.cnblogs.com/mythou/archive/2011/11/27/2265169.html    使用的时候,只要把 tinyxml.h、tinystr.h、tinystr.cpp、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.

idea lanyu方式激活

访问http://idea.lanyus.com/这个地址。根据提示将0.0.0.0 account.jetbrains.com添加到hosts文件中,hosts文件在C:\Windows\System32\drivers\etc目录下。点击获得注册码即可。

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

以canvas方式绘制粒子背景效果,感觉还可以

这个是看到项目中别人写好的,感觉这种写法效果还可以,就存留记录下 就是这种的背景效果。如果想改背景颜色可以通过canvas.js文件中的fillStyle值改。 附上demo下载地址。 https://download.csdn.net/download/u012138137/11249872

vue同页面多路由懒加载-及可能存在问题的解决方式

先上图,再解释 图一是多路由页面,图二是路由文件。从图一可以看出每个router-view对应的name都不一样。从图二可以看出层路由对应的组件加载方式要跟图一中的name相对应,并且图二的路由层在跟图一对应的页面中要加上components层,多一个s结尾,里面的的方法名就是图一路由的name值,里面还可以照样用懒加载的方式。 页面上其他的路由在路由文件中也跟图二是一样的写法。 附送可能存在