tigh 发表于 2018-8-26 07:14:28

浅谈shell—eval

  一、eval的基本用法
  eval会对后面的 cmdLine 进行两遍扫描,如果第一遍扫描后,cmdLine 是个普通命令,则执行此命令;
  如果 cmdLine 中含有变量的间接引用,则保证间接引用的语义。
  1.eval 命令将会首先扫描命令行进行所有的替换,然后再执行命令。该命令使用于那些一次扫描无法实现其功能的变量,且对变量进行两次扫描。需要进行两次扫描的变量被称为复杂变量。
  2.eval 也可以用于回显简单变量,不一定是复杂变量。
  3.两次扫描。
  例如:test.txt 内容:hello shell world!
  myfile="cat test.txt"
  (1)echo $myfile         #result:cat test.txt
  (2)eval echo $myfile  #result:hello shell world!
  从(2)可以知道第一次扫描进行了变量替换,第二次扫描执行了该字符串中所包含的命令。
  4.获得最后一个参数。
  例如:set 11 22 33 44
  如果要输出最近一个参数,即44,可以使用如下命令,
  echo $4
  但是如果我们不知道有几个参数的时候,要输出最后一个参数,大家可能会想到使用 $# 来输出最后一个参数。
  如果使用命令:
  echo "\$$#"
  则得到的结果是 $4,而不是我们想要的44。
  这里涉及到一个变量间接引用的问题,我们的本意是输出 44,默认情况下,命令后忽略变量间接引用的情况。
  使用eval命令就可以达到我们的预期:
  eval echo "\$$#"
  则得到的结果为44。
  二、shell 的 eval 同其他语言的区别
  shell 也提供了 eval 命令,将它的参数做为命令执行,初看会疑惑为什么 shell 要提供两种动态执行命令字串的机制,但是经过仔细分析,才发现shell的eval同其他语言有很大区别。
  1.shell 中的函数虽然可以通过return 返回,但是这里的return 相当于 exit,只能是个状态值用于测试,而不能像其它语言一样返回复杂的结果,其处理结果只能通过输出到标准输出经过 `` 和 $() 取得。
  2.shell 中的 eval
  a.不能获得函数处理结果 ,如1所说,所有命令,函数的处理结果只能通过 `` 来获得,那么其它语言中利用 eval 来获得动态生成代码执行后的输出变得不可能。
  b.eval 嵌套无意义 ,在其他语言中可以通过 eval(eval("code")) ,来执行(执行动态生成的 code 的返回),而由于shell 中 eval 将后面的 eval 命令简单当作命令字符串执行,失去了嵌套作用,嵌套被命令替换取代。

页: [1]
查看完整版本: 浅谈shell—eval