shell中eval的神奇之法,shell中引号的争端

话说大家都知道,shell中的变量是等价替换的。例如下面这个例子:



上面这个结果就是表示给变量cmd赋值为ls -lrt  ,然后直接使用变量就相当于执行了ls -lrt


因此在shell脚本中当然也可以这么写,例如:

<span style="font-family:Microsoft YaHei;font-size:12px;">#!/bin/bash

function main()
{
    cmd="pwd"
    $cmd
}

main $@
</span>

运行结果:



接下来我们看一个命令:

su - jeremysong -c "(pwd;. /media/jeremysong/document/test/source.sh;ls -lrt)"

它的直接结果如下:



然后我们写两个脚本,source.sh和runner.sh

<span style="font-family:Microsoft YaHei;font-size:12px;">#!/bin/bash
export DEVICE="Thinkpad SL410"
export OS="Ubuntu"

function print_time()
{
    date
}

function main()
{
    print_time
}

main $@
</span>

<span style="font-family:Microsoft YaHei;font-size:12px;">#!/bin/bash

function run()
{
    echo "------------------runner-----------START-------------"
    cmd="su - jeremysong -c \"(pwd;. /media/jeremysong/document/test/source.sh;ls -lrt)\""
    ${cmd}
    echo "------------------runner------------END--------------"
}

run $@
</span>


然而就在我们运行runner.sh的时候,情况出现了:


纳尼?!  为什么报错了?shell不是变量替换么,单独运行哪一行一点问题都没有,这是为什么?好,那么我们用调试模式看一下:


好吧,我们现在确认了是上面圈出来的那句出错了,那么这个能否正常执行呢?

答案肯定是不行的。

因为shell中的双引号和单引号虽然都可以表示字符串,但是两者还有差别的。

单引号用于保持引号内所有字符的字面值,即使引号内的\和回车也不例外,但是字符串中不能出现单引号。(注意是所有,只是单引号本身不能够出现在其中)。

双引号用于保持引号内所有字符的字面值(回车也不例外),但以下情况除外:

  • $加变量名可以取变量的值

  • 反引号仍表示命令替换

  • \$表示$的字面值

  • \`表示`的字面值

  • \"表示"的字面值

  • \\表示\的字面值

  • 除以上情况之外,在其它字符前面的\无特殊含义,只表示字面值。

下面看个例子:


可见,单引号中完全是保持字符串的原型输出,而双引号进行了命令替换。

所以我们可以修改runner.sh脚本成如下的写法:

<span style="font-family:Microsoft YaHei;font-size:12px;">#!/bin/bash

function run()
{
    echo "------------------runner-----------START-------------"
    cmd="su - jeremysong -c \"(pwd;. /media/jeremysong/document/test/source.sh;ls -lrt)\""
    eval $cmd
    echo "------------------runner------------END--------------"
}

run $@
</span>
我们在看看运行结果:



运行结果完全没问题。那么为何eval命令可以解决这个问题呢?

答案是,eval命令将会首先扫描命令行进行所有的置换,然后再执行该命令。该命令适用于那些一次扫描无法实现其功能的变量,就像我们刚才那样写的例子。

eval命令对变量进行两次扫描。这些需要进行两次扫描的变量有时被称为复杂变量。不过这些变量本身并不复杂。eval命令也可以用于回显简单变量,不一定是复杂变量。


那么,好了。这里要说的也就是怎么来处理问题了。如果读者对于shell中的单引号和双引号之间的差异,以及eval命令想要更进一步了解的话,可以多查查资料熟悉熟悉,这里就不一一介绍了。


知识点:

  • shell中单引号和双引号的区别
  • shell脚本的调试
  • shell命令eval


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值