Shell:eval和ksh命令之间的区别

时间:2016-08-30 14:25:35

标签: bash shell unix eval

在我的shell脚本中,我正在调用另一个用于ftping文件的脚本。目前如下:

eval doftp.sh -1 '"File Name with spaces.txt"'

如果文件名之间有空格,则不起作用。但是,如果我做如下更改,它的工作原理。

ksh doftp.sh -1 '"File Name with spaces.txt"'

那么eval命令有什么问题。我需要文件名带双引号。如果我没有错,我需要用eval命令逃避空间,那就是我错了,我相信。请确认。

1 个答案:

答案 0 :(得分:1)

首先,当然,“eval”可以做各种各样的事情,除了这里发生的事情。它指示shell重新评估其参数。例如,你可以这样做:

b=4
a='b'
eval "$a=3"
echo $b    # yields 3

这也意味着“eval”本质上有点危险,因为它会运行任何命令。

a='rm -rf /;b'
eval "$a=3"    #Removes all your files and sets b=3

在这种情况下,似乎“eval”只是剥离了一些引号。

eval doftp.sh -1 '"File Name with spaces.txt"'
# is equivalent to:
doftp.sh -1 "File Name with spaces.txt"

以shell脚本作为参数运行shell相当于只运行shell脚本。它不会重新处理参数 - 这意味着shell脚本中的某些东西可能需要这些引号。 (鉴于它被称为“doftp”,也许它将引用的字符串作为参数提供给“get”或“put”在FTP客户端。)

如果你有一个shell脚本“args.sh”打印你给它的参数,例如:

# args.sh
while [ "$#" -gt 0 ]; do echo "$1"; shift; done

你运行它就像你正在运行“doftp.sh”,这就是你所看到的:

$ ./args.sh unquoted '"String with     spaces"'
unquoted
"String with     spaces"
$ ksh ./args.sh unquoted '"String with     spaces"'
unquoted
"String with     spaces"

您正在运行该命令的shell剥离了单引号,但将包含 这些单引号中的字符串作为单个参数提供给命令''重新开始。然后可以使用“eval”再次执行

$ eval ./args.sh unquoted '"String with     spaces"'
unquoted
String with     spaces

......但显然这不是你想要的。当ksh将字符串作为其参数之一时,它会将该字符串保持为原样,除非您对其进行分词或其他操作。