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



我遇到了这行代码:

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

-f出现以测试文件名是否存在,但我不确定。到目前为止,谷歌搜索没有任何帮助(很难用谷歌搜索"-f"),我的Perl书也没有。

有人能提出建议吗?

请参阅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)

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

  • 普通(您认为是文件)
  • 目录
  • 命名管道
  • 命名套接字

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

-X运算符

查找Perl文件测试运算符。

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

似乎不是我误解了这个问题,就是其他人都误解了。

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

  1. 让我们假设您没有重载所有的-X前缀一元运算符(要么是全部,要么没有),

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

假设上面给出的这两个给定都成立,那么符号<filename>将执行scalar readline(*filename)——这取决于$/的值——然后将结果传递回filetest运算符进行后续评估,通常但不一定通过stat(2)。这意味着,除非涉及到真正的深层魔法,否则最好打开一个名为filename的文件句柄才能正常工作。

If也将对<$filename>执行此操作,只是现在$filename是一个间接句柄,而不是像filename那样的直接句柄。$/再次受到尊重。使用一个适合与之相关联的文件句柄的文件名实际上是我一直在做的事情。例如:

our $fn = "/etc/termcap";
open($fn, "<", $fn) || die "can't open $fn: $!";

通过这种方式,warndie消息实际上告诉我文件的名称。例如:

while (<$fh>) {
     warn "oops" if whatever;
}

会告诉我行号和我登录的文件名。

现在,如果<⋯>的操作数偏离了允许的无格与格对象的规则,即前缀为零或多个美元符号的裸字,那么它不是迭代运算符,而是通配符burster。即使没有通配符也是如此。它只需要违反Perl著名的数据规则,然后触发备用

这意味着如果且仅当filename不是一个具有零个或多个前导美元符号的合法裸字,例如/etc/termcap/tmp*.[Cchy]{,/usr}/bin/c?~/Documents,则调用File::Glob::bsd_glob函数指南中熟悉的旧聚合运算符,当提供适当的参数时,这正是您对这样一个有用且常用的函数所期望的结果。

以下是许多例子,显示了上面引用部分实际提出的问题的答案:

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"           } 

它测试<filename>指定的对象是否是普通文件(而不是二进制文件或目录等)。

相关内容

  • 没有找到相关文章

最新更新