Tim Asked: 2018-11-23 20:34:13 +0800 CST2018-11-23 20:34:13 +0800 CST 2018-11-23 20:34:13 +0800 CST `eval` 是否将 shell 应用于以下命令的重定向部分? 772 在命令上使用eval时,是否eval将 shell 两次应用于命令的重定向部分? 假设重定向中的文件名包含一个空格,如果eval多次对其进行解析、shell扩展和分词等所有步骤,则在第二轮分词步骤中,文件名将被拆分为两个单词。 以下示例是否暗示eval不会两次将 shell 应用于以下命令的重定向部分,因此文件名不会分成两个单词? $ filename="my file" $ eval "cat" < "$filename" hi bash eval 2 个回答 Voted Inian 2018-11-23T21:13:27+08:002018-11-23T21:13:27+08:00 有效的方法eval是将参数一起构建为一个要运行的 shell 命令。由于您的变量被引用,因此在构造此命令以运行时filename 它不会进行分词。 这可能不适用于您的文件名带有空格的情况,并且不带引号的扩展将导致错误。例如 filname=my\ file echo "dude" > my\ file eval cat < $filename bash: $filename: ambiguous redirect 请注意此处完成的分词,并cat收到错误的输入重定向文件名,从而导致错误。 还要注意,如果不是使用时的重定向cat,如果直接在文件上使用,eval会cat在这种情况下打开两个文件,即 eval cat $filename 将转化为跑步 cat my file 例如,如果您file在当前目录中命名了文件,它将显示其内容并显示文件不存在my于错误流中命名的文件。 filename=my\ file echo "foo" > file 我们正在使文件my不存在 eval cat $filename 2>&1 cat: my: No such file or directory foo Best Answer filbranden 2018-11-23T21:24:22+08:002018-11-23T21:24:22+08:00 在您提供的示例中,唯一eval得到的是cat,重定向发生在外部,eval并且文件作为eval "cat"命令的标准输入提供。 一种变体是使用单引号引用整个命令,包括重定向: $ eval 'cat < "$filename"' hi 现在eval正在获取整个字符串,包括重定向和变量名,因此它正在执行变量扩展和带空格的文件名所需的引用。这仍然有效。 另一种选择是对字符串使用双引号: $ eval "cat < '$filename'" hi 现在该变量已由 shell 扩展,但这仍然有效,因为其中的引号将文件名保持在一起。(请注意,如果文件名包含撇号,这会中断。) 什么不会“工作是这样的: $ eval "cat" "<" "$filename" 这与您的示例类似,但使用<引号后,外部 shell 不会执行重定向。eval然后将参数放在一起,生成的命令将是: cat < my file 这不会按预期工作,因为周围的报价my file现在已经消失了......
有效的方法
eval
是将参数一起构建为一个要运行的 shell 命令。由于您的变量被引用,因此在构造此命令以运行时filename
它不会进行分词。这可能不适用于您的文件名带有空格的情况,并且不带引号的扩展将导致错误。例如
请注意此处完成的分词,并
cat
收到错误的输入重定向文件名,从而导致错误。还要注意,如果不是使用时的重定向
cat
,如果直接在文件上使用,eval
会cat
在这种情况下打开两个文件,即将转化为跑步
例如,如果您
file
在当前目录中命名了文件,它将显示其内容并显示文件不存在my
于错误流中命名的文件。我们正在使文件
my
不存在在您提供的示例中,唯一
eval
得到的是cat
,重定向发生在外部,eval
并且文件作为eval "cat"
命令的标准输入提供。一种变体是使用单引号引用整个命令,包括重定向:
现在
eval
正在获取整个字符串,包括重定向和变量名,因此它正在执行变量扩展和带空格的文件名所需的引用。这仍然有效。另一种选择是对字符串使用双引号:
现在该变量已由 shell 扩展,但这仍然有效,因为其中的引号将文件名保持在一起。(请注意,如果文件名包含撇号,这会中断。)
什么不会“工作是这样的:
这与您的示例类似,但使用
<
引号后,外部 shell 不会执行重定向。eval
然后将参数放在一起,生成的命令将是:这不会按预期工作,因为周围的报价
my file
现在已经消失了......