用variables中的参数查找命令

> find /etc -name 'shells' /etc/shells # good !! > SEARCH="-name 'shells'"; find /etc $SEARCH # nothing found - bad !! 

为什么“查找”命令不能带参数variables?

其他命令在这种模式下工作正常。 这可能与空格和parsing有关。 我怎样才能在variables中构造params,然后用这个参数执行“find”?

为了清楚起见,我想制作一个名为xxxx -o -name -yyyyy -o -namezzzzz的链,然后通过一次运行find所有的文件

你的问题是简单的引号不是这样解释,而是作为你的参数。

你认为你已经执行了这个:

 find /etc -name 'shells' 

事实上,你已经执行了这个:

 find /etc -name \'shells\' 

请记住 :在bash中,双引号内的简单引号不会被忽略。

所以解决办法是不要放任何简单的引号:

 SEARCH="-name shells"; find /etc $SEARCH 

更好的解决scheme是使用引号,然后使用eval:

 SEARCH="-name 'shells'"; eval " find /etc $SEARCH" 

安全问题 :永远不要在eval参数中使用用户提供的信息。

尝试

 eval find /etc $SEARCH 
  • eval将在variables扩展之后评估该行

尝试像这样的名称选项:

SEARCH="shells"; find /etc -name $SEARCH

看看这个问题的一些选项。

我强烈build议避免eval – 它在简单的testing中往往工作得很好,但是在生产中,一些意想不到的shell元字符显示出来并造成严重破坏。 如果你有用户input的string,几乎可以保证你将面临安全问题。 考虑一下如果有人可以在文件模式列表中添加x'$(rm /somethingimportant)'yx'$(rm /somethingimportant)'y

对于这样的情况,你dynamic地构build一个命令,bash数组是一个更好的方法。 使用类似于:

 namepatterns=(-name xxxx) namepatterns+=(-o -name yyyyy -o -name "*.txt") # quotes prevent wildcard expansion while read pattern; do namepatterns+=(-o -name "$pattern") done <patternfile.txt find /etc "${namepatterns[@]}" 

"${array[@]}"成语将数组中的每个元素当作一个shell单词,而不会产生任何有问题的parsing(单词分割,通配符扩展)。

顺便说一句,我在上面的例子中稍微有点欺骗,把第一个-name xxxx primary添加到前面没有-o的数组中。 如果你完全在一个循环中构build数组,这将是棘手的:

 namepatterns=() while read pattern; do namepatterns+=(-o -name "$pattern") done <patternfile.txt # At this point the array starts with "-o" -- not what you want # So use array slicing to remove the first element: namepatterns=("${namepatterns[@]:1}") find /etc "${namepatterns[@]}" 

见BashFAQ#50:我试图把一个命令放在一个variables中,但是复杂的情况总是失败! 有关构build和存储命令的更多讨论和选项。