Perl中的if(-f <filename>)做什么?</filename>

时间:2011-05-30 06:28:01

标签: perl file

我遇到了这行代码:

if( -f <filename> ) { ... }

-f似乎测试文件名是否存在,但我不确定。到目前为止谷歌搜索还没有帮助(Google很难&#34; -f&#34;)而且我的Perl书也没有。

有人可以提供建议吗?

5 个答案:

答案 0 :(得分:31)

请参阅perlfunc

它列出了所有Perl内置函数,包括“文件测试”函数:

-X FILEHANDLE
-X EXPR
-X DIRHANDLE
-X

-X是以下之一:

-r: File is readable by effective uid/gid.
-w: File is writable by effective uid/gid.
-x: File is executable by effective uid/gid.
-o: File is owned by effective uid.

-R: File is readable by real uid/gid.
-W: File is writable by real uid/gid.
-X: File is executable by real uid/gid.
-O: File is owned by real uid.

-e: File exists.
-z: File has zero size (is empty).
-s: File has nonzero size (returns size in bytes).

-f: File is a plain file.
-d: File is a directory.
-l: File is a symbolic link.
-p: File is a named pipe (FIFO), or Filehandle is a pipe.
-S: File is a socket.
-b: File is a block special file.
-c: File is a character special file.
-t: Filehandle is opened to a tty.

-u: File has setuid bit set.
-g: File has setgid bit set.
-k: File has sticky bit set.

-T: File is an ASCII text file (heuristic guess).
-B: File is a "binary" file (opposite of -T).

-M: Script start time minus file modification time, in days.
-A: Same for access time.
-C: Same for inode change time (Unix, may differ for other platforms)

答案 1 :(得分:7)

在Unix中,目录可以包含以下类型的文件:

  • 平原(你会认为是什么文件)
  • 目录
  • 命名管道
  • 命名套接字
  • ...

-f测试提供的名称是否引用了普通文件的文件。如果文件不存在,它将返回undef(错误ENOENT),如果文件存在但是它不是普通文件(例如,如果它是目录),它将返回一些其他错误值。

-X operators

答案 2 :(得分:4)

答案 3 :(得分:2)

  

if (-f <filename> ) { ... }

似乎我误解了这个问题,或者其他人都有。

首先,让我们做一些假设。

  1. 假设您没有重载所有-X前缀一元运算符(它们都是全部或者都不是),

  2. 我们还假设您没有重载<>外围迭代运算符。

  3. 假设上面给出的这两个两个都有,那么符号<filename>将执行scalar readline(*filename) - 这取决于$/的值 - 然后将结果传回去到filetest运算符进行后续评估,通常但不一定通过 stat (2)。这意味着你最好有一个名为filename的文件句柄,以便工作,除非涉及到真正深刻的魔法。

    如果同时对<$filename>执行此操作,则现在除$filename之外的filename是间接句柄,而不是$/之类的直接句柄。同样,our $fn = "/etc/termcap"; open($fn, "<", $fn) || die "can't open $fn: $!"; 受到尊重。使用适合与之关联的文件句柄的文件名实际上就是我所做的所有术语。例如:

    warn

    这样diewhile (<$fh>) { warn "oops" if whatever; } 消息实际上告诉我文件的名称。例如:

    <⋯>

    会告诉我行号的行号和名称。

    现在,如果filename的操作数偏离允许的无支撑的dative对象的规则,即以零或更多美元符号为前缀的裸字,那么它不是迭代运算符而是通配符burster。即使没有通配符也是如此。它只需要违反Perl着名的 Datives规则,然后触发备用

    这意味着当且仅当 /etc/termcap不是具有零个或多个领先美元符号的合法裸字时 - 例如/tmp,{{1} },*.[Cchy]{,/usr}/bin/c?~/Documents - 然后调用File::Glob::bsd_glob函数指南中那个熟悉的旧的congobbulation运算符,你会得到完全相同的结果当提供适当的参数时,期望这样一个有用且常用的函数。

    以下是一些示例,显示了上述引用部分实际问的问题的答案:

    use v5.10;  # for the say feature, but not needed for conglobulation
    
    if (-d <~joebob>                 ) { say "joebob has a home"                 }
    if (-d <~joebob/.opera>          ) { say "joebob has an opera directory"     }
    if (-d <~joebob/.ssh>            ) { say "joebob has an ssh directory"       }
    
    if ($n = grep {-e} <~joebob/.*rc>) { say "joebob has $n RC files"            }
    
    if (-f <~joebob/.exrc>           ) { say "joebob has a vi config file"       }
    if (-f <~joebob/.profile>        ) { say "joebob has a sh profile"           }
    if (-f <~joebob/.bashrc>         ) { say "joebob has a bash config script"   }
    if (-f <~joebob/.cshrc>          ) { say "joebob has a csh config script"    }
    if (-f <~joebob/.log{in,out}*>   ) { say "joebob has csh login/out scripts"  }
    
    if (-S </tmp/.X*/X*>             ) { say "I smell an X11 socket"             }
    
    if (-t STDIN && -t STDOUT        ) { say "smells pretty tty to me"           } 
    

答案 4 :(得分:-3)

它测试<filename>指定的对象是纯文件(而不是二进制文件,还是目录等)。