我该如何防范“foreach:No match”?

时间:2013-08-20 17:46:50

标签: shell csh tcsh

我有一个看起来像这样的shell脚本:

foreach dir (i686.* amd64.*)
  # commands
end

此脚本的问题是,如果没有与这些名称匹配的目录,则会出现以下错误:

"foreach: No match."

防止此错误的优雅方法是什么?

2 个答案:

答案 0 :(得分:3)

以下是处理此问题的两种方法。

  1. 设置shell的nonomatch变量。如果它与任何文件都不匹配,这告诉tcsh保持模式不变。因此:

    % set nonomatch=1
    % echo i686.* amd64.*
    i686.* amd64.*
    

    然后,您需要让命令处理不匹配模式的情况。

  2. 传递一个总是匹配的额外模式。例如:

    % echo i686.* amd64.* /dev/nul[l]
    /dev/null
    

    然后,您需要使命令忽略始终匹配模式匹配的文件。这可能比#1更容易。

答案 1 :(得分:3)

您可以使用grepegrep而不是文件匹配模式:

foreach dir ( `ls | egrep '^(i686\|amd64)\.'` )
    # commands
end

如果没有文件匹配,ls | egrep ...命令就不会产生任何输出,并且循环体不会执行。

如果名称为dir,您可能需要添加一个测试,任何匹配的文件名实际上都是一个目录。

一个更丑陋的选择是临时创建匹配文件:

tmp=i686.$$
mkdir $tmp
foreach dir (i686.* amd64.*)
    if ($dir != $tmp) then
        # commands
    endif
end
rm $tmp

我不一定推荐这个。

如果您需要担心包含有趣字符的目录名称,您可能需要使用:q后缀或添加双引号。