-l $ _在Perl中做了什么,它是如何工作的?

时间:2013-03-05 13:40:41

标签: perl

嵌套代码的含义是什么

foreach (@items)
{
    if (-l $_)    ## this is what I don't understand: the meaning of -l
    {
        ...
    }
}

感谢您的帮助。

4 个答案:

答案 0 :(得分:6)

operator检查文件是否为符号链接。

答案 1 :(得分:6)

让我们看看每件事:

foreach (@items) {
    ...
}

for循环(foreachfor与Perl中的命令相同)从@items列表中获取每个项目,并将其设置为{{1} }。 $_是Perl中的一个特殊变量,用作默认变量的一种。这个想法是你可以做这样的事情:

$_

这些命令中的每一个都将对foreach (@items) { s/foo/bar/; uc; print; } 变量进行操作!如果您只是简单地说$_,则会打印print中的任何内容。如果您说$_并且没有提及变量,那么它将大写uc中的任何内容。

现在因为几个原因而不鼓励这样做。首先,$_全球,因此可能存在无意的副作用。例如,假设您调用了一个使用$_值进行混乱的子例程。您会突然惊讶于您的程序不起作用。

其他$_test运算符。此运算符检查给定的文件是否为符号链接。我已经链接到解释所有测试操作符的Perldoc。

如果您不熟悉Unix或BASH / Korn / Bourne shell脚本,那么使用以破折号开头的命令看起来很奇怪。但是,Perl的大部分语法都被盗了...我的意思是从Unix shell和awk命令中借用借用。在Unix中,有一个名为test的命令可以像这样使用:

-l

在Unix中,if test -L $FILE then .... fi test 命令的参数,而在Unix中,命令的大多数参数都以破折号开头。 Perl只是借用相同的语法破折号和所有。

有趣的是,如果您阅读这些测试命令的Perldoc,您会注意到-L循环,如果您没有给它变量,各种测试命令将使用foreach变量或文件名。编写该脚本的人可以像这样编写循环:

$_

是的,那太清楚了!

仅为了您的信息,许多Perl专家推荐的现代方式(咳嗽 Damian Conway 咳嗽)是为了避免尽可能foreach (@items) { if (-l) ## Notice no mention of the `$_` variable { ... } } 变量,因为它不会真正增加清晰度并可能导致问题。他还建议只说$_并忘记for,并在同一行使用花括号:

foreach

这可能对for my $file (@items) { if ( -l $file ) { ... } } 命令没有帮助,但至少你可以看到你正在处理文件,所以你可能会怀疑-l与文件有关。

不幸的是,Perldoc将所有这些文件测试放在-l部分下,并在 X 下按字母顺序排列,所以如果你在Perldoc中搜索-X命令,或任何以破折号开头的命令,除非你知道,否则你找不到它。但是,至少你现在知道将来在哪里看到这样的东西:-l

答案 2 :(得分:5)

-l filetest operator检查文件是否为符号链接。

-l在幕后工作的方式类似于下面的代码。

#! /usr/bin/env perl

use strict;
use warnings;

use Fcntl ':mode';

sub is_symlink {
  my($path) = @_;

  my $mode = (lstat $path)[2];
  die "$0: lstat $path: $!" unless defined $mode;

  return S_ISLNK $mode;
}

my @items = @ARGV;
foreach (@items) {
  if (is_symlink $_) {
    print "$0: link: $_\n";
  }
}

示例输出:

$ ln -s foo/bar/baz quux
$ ./flag-links flag-links quux
./flag-links: link: quux

请注意lstat而非stat的来电,因为后者会尝试关注符号链接,但从不识别它们!

要了解Unix模式位的工作原理,请参阅accepted answer to “understanding and decoding the file mode value from stat function output.”

答案 3 :(得分:4)

来自perldoc

 -l File is a symbolic link.