为了账号安全,请及时绑定邮箱和手机立即绑定

Bash中的eval命令及其典型用法

Bash中的eval命令及其典型用法

隔江千里 2019-10-23 14:46:45
在阅读了bash手册页并针对此帖子之后。我仍然很难理解该eval命令的确切功能以及它的典型用法。例如,如果我们这样做:bash$ set -- one two three  # sets $1 $2 $3bash$ echo $1onebash$ n=1bash$ echo ${$n}       ## First attempt to echo $1 using brackets failsbash: ${$n}: bad substitutionbash$ echo $($n)       ## Second attempt to echo $1 using parentheses failsbash: 1: command not foundbash$ eval echo \${$n} ## Third attempt to echo $1 using 'eval' succeedsone这里到底发生了什么,美元符号和反斜杠如何与问题联系在一起?
查看完整描述

3 回答

?
慕标琳琳

TA贡献1830条经验 获得超9个赞

eval将字符串作为其参数,并对其进行求值,就好像您在命令行上键入了该字符串一样。(如果您传递几个参数,则它们首先会以空格隔开。)


${$n}是bash中的语法错误。在大括号内,您只能具有一个变量名,并带有一些可能的前缀和后缀,但是您不能具有任意的bash语法,尤其是不能使用变量扩展。尽管有这样一种说法:“名称在此变量中的变量的值”:


echo ${!n}

one

$(…)在子外壳程序(即在一个单独的进程中,该命令在圆括号内)中运行,该命令继承了当前外壳程序的所有设置(例如变量值),并收集其输出。因此echo $($n),$n作为shell命令运行,并显示其输出。由于$n计算为1,因此$($n)尝试运行该命令1,该命令不存在。


eval echo \${$n}运行传递给的参数eval。展开后,参数为echo和${1}。因此eval echo \${$n}运行命令echo ${1}。


需要注意的是大部分的时间,因此必须将变量替换和命令替换双引号(即随时有一个$)"$foo", "$(foo)"。始终在变量和命令替换两边加上双引号,除非您知道需要将其省略。没有双引号,外壳程序将执行字段拆分(即,它将变量的值或命令的输出拆分为单独的单词),然后将每个单词视为通配符模式。例如:


$ ls

file1 file2 otherfile

$ set -- 'f* *'

$ echo "$1"

f* *

$ echo $1

file1 file2 file1 file2 otherfile

$ n=1

$ eval echo \${$n}

file1 file2 file1 file2 otherfile

$eval echo \"\${$n}\"

f* *

$ echo "${!n}"

f* *

eval不经常使用。在某些Shell中,最常见的用法是获取变量的值,该变量的名称直到运行时才知道。在bash中,由于${!VAR}语法原因,这不是必需的。eval当您需要构建包含运算符,保留字等的较长命令时,它仍然很有用。


查看完整回答
反对 回复 2019-10-23
  • 3 回答
  • 0 关注
  • 1221 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信