简介
eval
是Shell内置
的命令。基本用法如下:
eval [arguments]
主要功能是读入arguments
并执行之。arguments
的退出码(Exit Code)
会被当做eval
的退出码
。如果没有arguments
,则退出码
是0
。
在平时的使用中,我们一般会用到eval
的2个特性。
两次扫描参数
cat >parse_twice.sh<<EOF""
#!/bin/bash
x=100
y=x
eval echo \$$y
eval $y=50
echo $x
eval echo \$$y
EOF
chmod a+x parse_twice.sh
./parse_twice.sh
# 输出
100
50
50
上面例子中的eval echo \$$y
首先被读取,然后被执行:在读取的过程中,$y
会被替换成x
,所以读取的结果是echo $x
;执行echo $x
的输出就是打印了变量x
的值。同理,eval $y=50
会被解析成x=50
,然后执行x=50
的结果就是为变量x
赋值。
执行复杂的字符串形式的命令
cat >complex_command.sh<<EOF""
#!/bin/bash
dirpath=/Users/lishaolin/Workspace/Shell/eval
simple_cmd="ls -l $dirpath"
complex_cmd="ls -l $dirpath | awk -F ' ' '{print \$9}'"
echo '=========================='
echo '========Simple Cmd========='
echo '=========================='
eval $simple_cmd
echo '-----------------------------------'
$simple_cmd
echo '==========================='
echo '========Complex Cmd========='
echo '==========================='
eval $complex_cmd
echo '-----------------------------------'
$complex_cmd
EOF
chmod a+x complex_command.sh
./complex_command.sh
# 输出
==========================
========Simple Cmd=========
==========================
total 16
-rwxr-xr-x 1 lishaolin staff 497 3 17 16:30 complex_command.sh
-rwxr-xr-x 1 lishaolin staff 71 3 17 15:41 parse_twice.sh
-----------------------------------
total 16
-rwxr-xr-x 1 lishaolin staff 497 3 17 16:30 complex_command.sh
-rwxr-xr-x 1 lishaolin staff 71 3 17 15:41 parse_twice.sh
===========================
========Complex Cmd=========
===========================
complex_command.sh
parse_twice.sh
-----------------------------------
ls: $9}': No such file or directory
ls: ': No such file or directory
ls: ': No such file or directory
ls: '{print: No such file or directory
ls: -F: No such file or directory
ls: awk: No such file or directory
ls: |: No such file or directory
/Users/lishaolin/Workspace/Shell/eval:
total 16
-rwxr-xr-x 1 lishaolin staff 497 3 17 16:30 complex_command.sh
-rwxr-xr-x 1 lishaolin staff 71 3 17 15:41 parse_twice.sh
可以看到,在执行$simple_cmd
时,是否使用eval
的效果是相同的。但是当我们执行一个稍微复杂一点(比如包含管道(Pipe)
)的字符串形式的命令时,如果不使用eval
,执行会报错!