foreach随机不匹配

时间:2015-05-12 08:48:49

标签: foreach csh

这是代码:

set source_failed = `cat mine.log`

set dest_failed = `cat their.log`

foreach t ($source_failed)
  set isdiff = 0
  set sflag = 0
  foreach t2 ($dest_failed)
    if ($t2 == $t) then
      set sflag = 1
      break
    endif
  end
  ...
end

问题是内部foreach循环在前10次迭代中运行正常。在那次迭代之后,我突然得到了

foreach: no match

此外,我正在迭代字符串数组,而不是文件。这个错误背后的原因是什么?

1 个答案:

答案 0 :(得分:0)

问题是(可能)mine.log和/或their.log包含特殊的通配符,例如*?。 shell将尝试将其扩展为文件。这种偶然模式没有匹配,因此错误"不匹配"。

防止此行为的最简单方法是将set noglob添加到顶部。来自tcsh(1)

    noglob  If set, Filename substitution and Directory stack  substitution
           (q.v.)  are  inhibited.   This  is most useful in shell scripts
           which do not deal with filenames, or after a list of  filenames
           has been obtained and further expansions are not desirable.

您可以使用set glob重新启用此行为。

另外,您可以使用:q。来自tcsh(1)

Unless  enclosed in `"' or given the `:q' modifier the results of variable
substitution may eventually be command and  filename  substituted.

[..]

When the `:q' modifier is applied to a substitution the variable will expand
to multiple words with  each  word  sepa rated  by  a blank and quoted to
prevent later command or filename sub stitution.

但是在使用变量时需要非常小心引用。在下面的示例中,如果您不添加引号(echo),set noglob is much easier命令将失败:

set source_failed = `cat source`

foreach t ($source_failed:q)
    echo "$t"
end