在我的shell脚本中,我正在调用另一个用于ftping文件的脚本。目前如下:
eval doftp.sh -1 '"File Name with spaces.txt"'
如果文件名之间有空格,则不起作用。但是,如果我做如下更改,它的工作原理。
ksh doftp.sh -1 '"File Name with spaces.txt"'
那么eval命令有什么问题。我需要文件名带双引号。如果我没有错,我需要用eval命令逃避空间,那就是我错了,我相信。请确认。
答案 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将字符串作为其参数之一时,它会将该字符串保持为原样,除非您对其进行分词或其他操作。