Chinaunix

标题: 为什么用eval可以正常执行的命令,用`却无法正确执行? [打印本页]

作者: bikkuri    时间: 2016-11-23 04:40
标题: 为什么用eval可以正常执行的命令,用`却无法正确执行?
本帖最后由 bikkuri 于 2016-11-23 05:15 编辑

大家好!
我有一个问题向大家请教。
请看以下这些命令的执行结果:
[root@hp8:~]# cat t
if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
[root@hp8:~]# if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
YES
[root@hp8:~]# eval $(cat t)
YES
[root@hp8:~]# `cat t`
-bash: if: command not found
[root@hp8:~]#

请问为什么用eval可以正常执行这条命令,用backtick反引号`却无法正确执行?
假如换一条简单的不含有if的命令,比如date,用`是可以正确执行的,比如:
[box@iZ94mso98zxZ:~]$ cat d
date
[box@iZ94mso98zxZ:~]$ `cat d`
Wed Nov 23 04:55:40 CST 2016
[box@iZ94mso98zxZ:~]$

那么为什么用`无法执行if语句呢?
[box@iZ94mso98zxZ:~]$ `$(cat t)`
-bash: if: command not found
[box@iZ94mso98zxZ:~]$ `cat t`
-bash: if: command not found
[box@iZ94mso98zxZ:~]$ cat t
if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
[box@iZ94mso98zxZ:~]$ $(cat t)
-bash: if: command not found
[box@iZ94mso98zxZ:~]$ eval $(cat t)
YES
[box@iZ94mso98zxZ:~]$ eval `cat t`
YES
[box@iZ94mso98zxZ:~]$ ``cat t``
if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
[box@iZ94mso98zxZ:~]$ ```cat t```
-bash: if: command not found
[box@iZ94mso98zxZ:~]$
如果不用eval只用`应该如何正确执行这个命令呢?
[box@iZ94mso98zxZ:~]$ touch $(if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi).txt
[box@iZ94mso98zxZ:~]$ ls -l *.txt
-rw-rw-r-- 1 box box    0 Nov 23 05:08 YES.txt
[box@iZ94mso98zxZ:~]$ rm -f YES.txt
[box@iZ94mso98zxZ:~]$ touch `if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi`.txt
[box@iZ94mso98zxZ:~]$ ls -l *.txt
-rw-rw-r-- 1 box box    0 Nov 23 05:09 YES.txt
[box@iZ94mso98zxZ:~]$ rm -f YES.txt
[box@iZ94mso98zxZ:~]$ touch $(eval $(cat t)).txt
[box@iZ94mso98zxZ:~]$ ls -l *.txt
-rw-rw-r-- 1 box box    0 Nov 23 05:10 YES.txt
[box@iZ94mso98zxZ:~]$ rm -f YES.txt
[box@iZ94mso98zxZ:~]$ touch `$(cat t)`.txt
-bash: if: command not found
[box@iZ94mso98zxZ:~]$
谢谢大家!



base64.png (12.59 KB, 下载次数: 38)

base64.png

作者: fh21_xuejinlian    时间: 2016-11-23 11:36
`cat t`  = $(cat t),eval $(cat t) = eval `cat t`
作者: chengchow    时间: 2016-11-23 11:45
`cat t` == 将文件t内容做为一条命令执行
eval `cat t` == 先执行cat t,再将执行结果做为命令执行
作者: bikkuri    时间: 2016-11-23 16:36
chengchow 发表于 2016-11-23 11:45
`cat t` == 将文件t内容做为一条命令执行
eval `cat t` == 先执行cat t,再将执行结果做为命令执行

现在的问题是为什么用`cat t`可以执行象date这样的命令,却不能执行if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi这种含有if的命令?

作者: bikkuri    时间: 2016-11-23 16:46
即使没有if,有分号;也不行。
[box@iZ94mso98zxZ:~]$ cat t
date;
[box@iZ94mso98zxZ:~]$ echo `date;`
Wed Nov 23 16:44:53 CST 2016
[box@iZ94mso98zxZ:~]$ cat t
date;
[box@iZ94mso98zxZ:~]$ `cat t`
-bash: date;: command not found
[box@iZ94mso98zxZ:~]$ eval $(cat t)
Wed Nov 23 16:45:06 CST 2016
[box@iZ94mso98zxZ:~]$
为什么eval可以正确执行,而`不行呢?
有哪位高手能帮忙解释一下?????
作者: bikkuri    时间: 2016-11-23 17:00
看来是加了分号;后,cat t的结果会被加上一对引号
[box@iZ94mso98zxZ:~]$ cat t
date;
[box@iZ94mso98zxZ:~]$ cat d
date
[box@iZ94mso98zxZ:~]$ set -x
++ printf '\033]0;%s@%s:%s\007' box iZ94mso98zxZ '~'
[box@iZ94mso98zxZ:~]$ `cat t`
++ cat t
+ 'date;'
-bash: date;: command not found
++ printf '\033]0;%s@%s:%s\007' box iZ94mso98zxZ '~'
[box@iZ94mso98zxZ:~]$ `cat d`
++ cat d
+ date
Wed Nov 23 16:57:06 CST 2016
++ printf '\033]0;%s@%s:%s\007' box iZ94mso98zxZ '~'
[box@iZ94mso98zxZ:~]$ eval $(cat t)
++ cat t
+ eval 'date;'
++ date
Wed Nov 23 16:57:24 CST 2016
++ printf '\033]0;%s@%s:%s\007' box iZ94mso98zxZ '~'
[box@iZ94mso98zxZ:~]$ eval $(cat d)
++ cat d
+ eval date
++ date
Wed Nov 23 16:57:27 CST 2016
++ printf '\033]0;%s@%s:%s\007' box iZ94mso98zxZ '~'
[box@iZ94mso98zxZ:~]$ set +x
+ set +x
[box@iZ94mso98zxZ:~]$ 'date'
Wed Nov 23 16:58:08 CST 2016
[box@iZ94mso98zxZ:~]$ 'date;'
-bash: date;: command not found
[box@iZ94mso98zxZ:~]$
还是搞不懂为什么eval就是可以而`就是不行。。。。。。
作者: bikkuri    时间: 2016-11-25 08:42
没有人能回答一下我的问题吗???
作者: 重楼君    时间: 2016-11-25 09:30
回复 7# bikkuri
  1. [root@hp8:~]# cat t
  2. if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
  3. [root@hp8:~]# if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi
  4. YES
  5. [root@hp8:~]# eval $(cat t)
  6. YES
  7. [root@hp8:~]# `cat t`
  8. -bash: if: command not found
  9. [root@hp8:~]#
复制代码
man eval就可以找到答案了。
eval的作用是将所给的命令解析两次。``与$()一样,只是执行命令。

你的t相当于一个变量,值是“if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi”。
``(或$())时,整个命令是cat t --> cat if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi --> 这条命令当然执行不了。
eval cat t --> cat t的值(因为eval先把t的变量,也这就是“if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES”这条命令执行了,得到t的值)-- 这样当然可以执行。






作者: bikkuri    时间: 2016-11-25 10:11
重楼君 发表于 2016-11-25 09:30
回复 7# bikkuri man eval就可以找到答案了。
eval的作用是将所给的命令解析两次。``与$()一样,只是执行 ...

你理解错了,t是一个文件,文件的内容是if [ $(ls -l|grep -c t) -eq 0 ];then echo NO;else echo YES;fi


作者: bikkuri    时间: 2016-11-25 10:17
请回答一个简单的问题吧。
[box@iZ94mso98zxZ:~]$ `echo "date;"`
-bash: date;: command not found
[box@iZ94mso98zxZ:~]$ `echo "date"`
Fri Nov 25 10:15:04 CST 2016
[box@iZ94mso98zxZ:~]$
为什么有分号就出错?
作者: bikkuri    时间: 2016-11-25 10:18
为什么这样又不出错?
[box@iZ94mso98zxZ:~]$ echo `date`
Fri Nov 25 10:18:17 CST 2016
[box@iZ94mso98zxZ:~]$ echo `date;`
Fri Nov 25 10:18:19 CST 2016
[box@iZ94mso98zxZ:~]$

作者: sditmaner    时间: 2016-11-25 12:52
支持一下 楼主加油

作者: bikkuri    时间: 2016-11-30 08:06
还是没有解决这个问题,很苦恼!
有哪位高手指点一下吧,拜托了!

回复 12# sditmaner



作者: 爻易    时间: 2016-12-04 10:20
date是可执行文件,而if/eval是解释器的内部命令,只能由解释器进行解释而不能直接执行。

当看到if: command not found之类的,就是把if当成可执行文件了,而实际没有if文件则报错
作者: 爻易    时间: 2016-12-04 10:24
#date
2016年 12月 04日 星期日 10:09:11 CST

执行date的输出则报错,因为不存在“2016年”这个命令:
#2016年 12月 04日 星期日 10:09:11 CST
bash: 2016年: 未找到命令

这相当`date`,结果是同样的报错:
#`date`
bash: 2016年: 未找到命令






欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2