代码之家  ›  专栏  ›  技术社区  ›  cowgod

为什么在调用open()的文件名上使用cat?

  •  1
  • cowgod  · 技术社区  · 15 年前

    我在一个遗留的Perl应用程序中遇到了一行非常奇怪的代码。这里的代码是国产RSS阅读器的一部分,它执行一些缓存以防止被列入黑名单。

    open(CAT, "/usr/bin/cat -v /tmp/cat-cache 2>&1|");
    

    最初的作者是否有可能将结果 cat -v 去除非打印字符以处理任意数量的字符集?在Perl中使用正则表达式是否更有意义?而且,我最为困惑的是最后的管道。

    4 回复  |  直到 13 年前
        1
  •  4
  •   Kent Fredric    15 年前

    功能上

    该代码的作用类似于:

    open my $fh, '<' , '/tmp/cat-cache' or Carp::croak("Cant open file $@ $! ");
    
    sub lessquote {
        my $x  = shift;
        my $meta = shift; # meta means were repeating thise code for >128
        # Special Case for whitespace 
        if(( not defined $meta ) && ( $x  == 9 or $x == 10 ) ){
            return chr($x);
        }
        # Null and M-^@
        if(  $x  == 0 ){ 
            return "^@"; 
        }
        # ^A to ^Z as well as M-^A to M-^Z
        if( ( 0 <= $x ) && ( $x  <= 31 )){
            return "^" . chr( $x + ord('A') - 1 );
        }
        # Also M-^?
        if( $x == 127 ){ 
            return "^?";
        } 
        # Does the M- Family
        if( $x >= 128 && $x <= 255 ){ 
            return "M-" . lessquote( $x - 128 , 1); 
        }
        return chr( $x );
    }
    
    while( my $line = <$fh> ){
       $line =~ s{(.)}{ lessquote( ord( $1 ) ) }eg;
    }
    

    不相同,但相似。

    注意:lessquote似乎与我的“cat-v”输出匹配。

    但是正如你所看到的,做同样的事情比琐碎的事情要少些,也不直接适合于正则表达式,但是,我仍然不明白为什么它们会突然变成“cat”。

    就他们的风格而言

    他们正在以一种糟糕的方式炮击,代码样式是1990年代的风格,应该避免。

    open my $fh , '-|' , 'cat' , '-v' , '/tmp/cat-cache' or Carp::croak("Cant open file $@ $! ");
    

    Syntax:

    open my $FILEHANDLE , $OPENMODE, $FILENAME            || Carp::croak($ERRORMESSAGE)
    open my $FILEHANDLE , $OPENMODE, $SHELLCOMMAND        || Carp::croak($ERRORMESSAGE) 
    open my $FILEHANDLE , $OPENMODE, $SHELLPROGRAM, @ARGS || Carp::croak($ERRORMESSAGE)
    

    这些天的“首选”符号有很多原因。 当然,你不会 事实上 想使用cat,但为了一个明确的例子,我把它留在这里。

        2
  •  11
  •   Tim Cooper    13 年前

    它看起来像“cat-v”显示文件中的所有非打印字符,这样您就可以实际看到crlfs、tab等。

    管道是Perl如何识别 打开 命令:这不是一个简单的文件,而是从该命令打开管道输出。

        3
  •  2
  •   Daniel Martin    15 年前

    你可能想看看 perl open tutorial .

    基本上,传递给open的“文件名”末尾的管道会导致名为该文件的程序被执行,并将输出发送给Perl。类似地,您可以使用“文件名”开头的管道将输出管道输出到外部程序。

    在Perl程序内部这样做可能更有意义,但是引用的代码更符合三者中的两个。 prime virtues of a Perl programmer .

        4
  •  0
  •   hpavc    15 年前

    最初的作者在某一点上感到困惑,或者有一只setuid猫:)

    关于“cat-v”的一些困惑…

       -v, --show-nonprinting
                  use ^ and M- notation, except for LFD and TAB
    

    …它不像“字符串”(字符串-打印文件中可打印字符的字符串)。

    $ strings /bin/rm | head
    /lib/ld-linux.so.2
    e="?
    __gmon_start__
    libc.so.6
    _IO_stdin_used
    fflush
    setlocale
    mbrtowc
    strncmp
    optind