在Perl中,没有$or@的情况下,什么是(单下划线)?

在Perl中,没有$or@的情况下,什么是(单下划线)?,perl,Perl,我有一些这样的代码: if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) { raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n") } 我可以在Perl中找到关于@和$的信息,但不仅仅是关于的信息。 这里的-d和-o是什么意思?当与操作员一起使用时,使用上一个文件测试的stat结构 如果任

我有一些这样的代码:

if (!-d _ || !-o _ || ($vncUserDirUnderTmp && ($mode & 0777) != 0700)) {
    raise Exception("$prog: Wrong type or access mode of $vncUserDir.\n")
}
我可以在Perl中找到关于
@
$
的信息,但不仅仅是关于
的信息。 这里的
-d
-o
是什么意思?

当与操作员一起使用时,使用上一个文件测试的
stat
结构

如果任何文件测试(或
stat
lstat
运算符)被赋予由单独下划线组成的特殊文件句柄,则使用上一个文件测试(或
stat
运算符)的
stat
结构,保存系统调用。

例如:

stat($filename);  
print "Readable\n" if -r _;  
print "Writable\n" if -w _;
...
因此,在您的示例中,
-d 
测试文件last
stat
-ed是否不是目录

更新

不寻常的
实际上是一个类型glob
*
,但是对于需要文件句柄的操作符,
*
可能会被省略,就像
可能被写成
一样。它可以在符号表中找到

print *{$main::{_}}{IO}, "\n";   # -->  IO::Handle=IO(0x2311970)

在一行程序中,
*.\ucode>只有在调用了
stat
之后才能设置。

当您调用一个文件测试操作符(
-f
-d
-s
等)时,Perl实际上调用了操作系统的
stat
函数。
stat
函数返回一个结构,其中包含有关所讨论文件的各种有趣信息,但每个文件测试操作符只查看该结构中的一个字段(它是文件吗?它是目录吗?它有多大?)

通常,您可能希望了解更多关于文件的一条信息(它是文件吗?我可以读取它吗?我可以执行它吗?)。简单的编写方法是:

if (-f $file and -r $file and -x $file)
但这会对
stat
进行三次调用,每次调用只查看结构中的一个字段。为了缓解这种情况,Perl非常聪明,它缓存了最近调用
stat
的结果。它被缓存在特殊的文件句柄
上。因此,编写相同代码的更有效方法是:

if (-f $file and -r _ and -x _)
这只需要调用一次
stat

从Perl 5.10开始,您还可以使用“堆叠文件测试”,并将此代码编写为:

if (-x -r -f $file) # Note reversed order of operators
更新:是关于堆叠文件操作符的

从Perl 5.10.0开始,作为纯语法糖的一种形式,您可以 堆栈文件测试操作符,其方式是
-f-w-x$file
相当于
“-x$file&&-w&&&f&
(这只是一种幻想) 语法:如果使用
-f$file
的返回值作为参数 对于另一个filetest操作符,不会发生特殊的魔法。)


!-d
测试文件是否不是目录。
-o
检查文件所有权对于使用文件句柄的操作员,您可以传递glob的名称。
-d
-d*.
的缩写,就像
打印标准输出…
打印标准输出…
的缩写,您的代码实际读取“if(…):raiseexception(…)“?该语法是否来自某个模块?@Kim TightVNC源代码不包含该语法。TightVNC-1.3.10_unixsrc.tar.bz2的vncserver包含
if(!-d | |!-o | |($vncUserDirUnderTmp&($mode&0777)!=0700)){die“$prog:错误的类型或$vncUserDir的访问模式。\n”}
。您在问题中提出的内容看起来像是Perl和Python的奇怪混合。啊……这是我的错误。我曾尝试将Perl代码转换为Python。我编辑了代码。对不起,它们实际上是排队的(从左到右执行),对吧?我今天学到了一些新东西!(不知道可堆叠文件测试。)但是这个stat缓存的初始值是什么?我注意到它包含一些东西,即使之前没有stat调用。它只是随机垃圾吗?@AnT一个有趣的问题。我猜它可能引用脚本本身,但我无法从中得到任何东西。在其他尝试中,我打印了所有的文件测试(比如
-s
),并且它们都是
undef
。因此我无法确认
stat
缓存是否已设置(而句柄本身
*.
已设置)。