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命令,因为它能将传给他的参数作为命令执行,即使你可能不知道这个参数的具体值,这会导致安全性问题。

  • 35
    点赞
  • 37
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
### 回答1: Linux中的eval命令是一个用于将字符串转换为命令行语句并执行命令。它将解析执行由引号括起来的参数作为一条命令,可以将变量、函数和算术运算符的值作为参数传递到该命令eval命令在编写shell脚本时非常有用,可以让你将动态生成的代码作为命令执行。然而,使用eval命令时要非常小心,因为它可能会有安全问题,特别是当它的参数来自不可信的来源时。 ### 回答2: eval命令Linux系统中的一个内置命令,用于执行一个字符串作为命令并在当前shell环境中运行。eval命令的基本语法是"eval [字符串]"。 eval命令的主要作用是将字符串作为命令执行,字符串中可以包含命令、变量、表达式等,eval命令会将字符串作为一个整体解析执行。这个功能非常有用,特别是在需要动态构建命令或者在脚本中使用变量时。 eval命令的常见用法如下: 1. 动态构建命令: 可以通过将命令和变量组合成字符串,然后使用eval命令执行。例如,可以使用eval命令来循环执行一组命令,或者动态构建带有变量的复杂命令。 2. 执行字符串表达式: eval命令可以将字符串作为表达式进行求值。这在需要动态计算数学表达式时非常有用。例如,可以将一个包含数学计算的字符串作为参数传递给eval命令,然后返回计算结果。 3. 使用变量: eval命令可以解析字符串中的变量,并将其替换为实际的值。这样可以在脚本中灵活地使用变量,并且可以根据需要在运行时进行动态更改。 然而,eval命令需要小心使用,因为它可以执行任何命令,可能导致潜在的安全风险。应该避免将来自不受信任的源的字符串传递给eval命令,以防止执行恶意代码。同时,应该谨慎处理字符串中的变量,确保不会受到注入攻击的风险。 总之,eval命令Linux系统中非常强大和灵活的一个命令,可以用于动态构建和执行命令、求值表达式以及使用变量。适当地使用eval命令可以提高脚本的灵活性和效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日晨难再

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值