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

adi*_*dir 4 perl

嵌套代码的含义是什么?

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

谢谢你的帮助.

ike*_*ami 6

它是一个运算符,用于检查文件是否为符号链接.


Dav*_* W. 6

让我们看看每件事:

foreach (@items) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

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

foreach (@items) {
    s/foo/bar/;
    uc;
    print;
}
Run Code Online (Sandbox Code Playgroud)

并且每个命令都将对该$_变量进行操作!如果你只是简单地说print,它会打印出任何内容$_.如果你说uc并且没有提到变量,它将大写任何内容$_.

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

另一个-l测试操作员.此运算符检查给定的文件是否为符号链接.我已经链接到解释所有测试操作符的Perldoc.

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

if test -L $FILE
then
    ....
fi
Run Code Online (Sandbox Code Playgroud)

在Unix中,那-L是一个参数测试命令,在Unix的,大多数参数的命令开始划线.Perl只是借用了相同的语法破折号和所有.

有趣的是,如果您为这些测试命令读取Perldoc,您会注意到,就像foreach循环一样,$_如果您没有为变量或文件名提供变量,各种测试命令将使用该变量.编写该脚本的人可以像这样编写循环:

foreach (@items)
{
    if (-l)   ## Notice no mention of the `$_` variable
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

是的,那太清楚了!

只是为了您的信息,许多Perl专家(咳嗽Damian Conway 咳嗽)推荐的现代方法是尽可能避免变量,因为它不会真正增加清晰度并可能导致问题.他还建议只说和忘记,并在同一行使用花括号: $_forforeach

for my $file (@items) {
    if ( -l $file ) {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这可能对-l命令没有帮助,但至少你可以看到你正在处理文件,所以你可能会怀疑这-l与文件有关.

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


Gre*_*con 5

-lfiletest操作检查文件是否是一个符号链接.

-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";
  }
}
Run Code Online (Sandbox Code Playgroud)

样本输出:

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

请注意调用lstat而不是stat因为后者会尝试遵循符号链接但从不识别它们!

要了解Unix模式位的工作原理,请参阅"从stat函数输出中理解和解码文件模式值"的已接受答案.