【问题标题】:Can awk skip files which do not exist, race-free?awk 可以跳过不存在的文件吗?
【发布时间】:2010-09-18 01:09:54
【问题描述】:

有没有办法让 awk (gawk) 忽略或跳过丢失的文件?也就是说,通过命令行传递的文件不再存在于文件系统中(例如 /proc/[1-9]* 下快速出现/消失的文件)。

默认情况下,丢失文件是致命错误:-(

我希望能够做类似这样的事情:

BEGIN { MISSING_FILES_ARE_FATAL = 0 }  # <- Wishful thinking!
      { count++ }
END   { print count }

包装脚本无法在 awk 运行之前检查文件是否存在,因为它们可能会在检查它们和 awk 尝试打开它们之间消失,即,这是一个竞争条件。 (在awk中check-then-open也是一种竞争条件,虽然时间比较紧)

【问题讨论】:

    标签: error-handling awk race-condition gawk


    【解决方案1】:

    GAWK 4 有BEGINFILE,您可以在其中测试ERRNO,如果ERRNO 不为空(表示文件无法打开),则执行nextfile

    【讨论】:

      【解决方案2】:

      即使在你的 awk 脚本周围加上一个 perl 或 shell 包装器,我认为仍然会有竞争条件。例如,使用 ADEpt 的其他很好的 shell sn-p:

      [ -r "$filename" ] && awk -f ... $filename
      

      没有什么可以阻止进程在 -r 和 awk 尝试打开文件之间消失...

      我能想到的唯一答案是使用 LD_PRELOAD 代替 awk 的系统打开调用,这样如果文件丢失,则打开 /dev/null 上的读取文件描述符。

      这可能行得通...

      【讨论】:

        【解决方案3】:

        你可以通过系统调用检查ARGV的内容,然后通过getline处理它们。

         if (system("test -r " ARGV[1]) == 0)
           while ( (getline aline < ARGV[1]) >0 )
             # process ARGV[1] via `aline` instead of $0
        

        ...

        然后处理ARGV[2]等 高温

        【讨论】:

          【解决方案4】:

          在我看来,“MISSING_FILES_ARE_FATAL = 0”功能将成为下一个 gawk 版本的一部分。查看当前 gawk-stable 源代码的 ChangeLog 文件:

          --- 剪断 ---

          2008 年 8 月 22 日星期五 14:43:49 Arnold D. Robbins

          * io.c (nextfile): Users Strong In The Ways Of The Source can use
          non-existant files on the command line without it being a fatal error.
          

          --- 剪断 ---

          http://cvs.savannah.gnu.org/viewvc/gawk-stable/ChangeLog?revision=1.87&root=gawk&view=markup

          赫尔曼

          【讨论】:

            【解决方案5】:

            按照最好的传统,我将使用 Perl 程序回答您的 awk 问题。

            #!/usr/bin/perl -w
            
            for my $file (@ARGV) {
                open my $fh, $file or next;
                while(<$fh>) {
                    ...do your thing here...
                }
            }
            

            (这不是 awk,但它是唯一没有竞争条件的解决方案。)

            【讨论】:

              【解决方案6】:

              哦,对不起。忽略我之前的回答。这是另一个建议:

              cat /proc/[1-9]* 2>/dev/null | awk ....
              

              Cat 会吞噬所有文件,无论是丢失的还是现有的,cat 的错误都会被遗忘(丢失的文件对 cat 来说是非致命错误),并且 awk 将能够处理结果。

              【讨论】:

                猜你喜欢
                • 2021-12-19
                • 1970-01-01
                • 2013-02-04
                • 2014-06-29
                • 2013-08-02
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2015-02-22
                相关资源
                最近更新 更多