加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Perl的文件测试运算符-f为符号链接返回true

发布时间:2020-12-15 21:19:10 所属栏目:大数据 来源:网络整理
导读:我曾经认为, – 测试了一个文件,看它是否是一个常规文件,而不是其他任何东西。但是Perl似乎有所不同。我查看了 perldoc条目,它说: -f File is a plain file. 假设我有一个目录有一个名为file1的文件和5个符号链接1 2 3 4 5,每个文件指向file1,如下所
我曾经认为, – 测试了一个文件,看它是否是一个常规文件,而不是其他任何东西。但是Perl似乎有所不同。我查看了 perldoc条目,它说:
-f  File is a plain file.

假设我有一个目录有一个名为file1的文件和5个符号链接1 2 3 4 5,每个文件指向file1,如下所示:

-rw-r--r-- file1
lrwxrwxrwx 1 -> file1
lrwxrwxrwx 2 -> file1
lrwxrwxrwx 3 -> file1
lrwxrwxrwx 4 -> file1
lrwxrwxrwx 5 -> file1
drwxr-xr-x ../
drwxr-xr-x ./

如果我使用-type f过滤器在此目录下运行,则会按预期的方式输出:

%  find . -type f
./file1

但是当我使用-f运算符运行一个perl脚本时,它会提供以下输出:

%  ls | perl -e 'while(<>) { chomp; print "$_n" if -f $_ }'
1
2
3
4
5
file1

当我也添加了-l的测试,它的工作原理:

%  ls | perl -e 'while(<>) { chomp; print "$_n" if -f $_ and not -l $_}'
file1

符号链接是否也被视为普通文件?如果是,为什么?我使用的文件测试不正确吗?

解决方法

快速解决方案
$ ls | perl -lne 'print if stat && -f _'
1
2
3
4
5
file1

$ ls | perl -lne 'print if lstat && -f _'
file1

符号链接并找到

默认情况下,GNU找不到引用或遵循符号链接,但find documentation描述了更改此策略的交换机。

The options controlling the behaviour of find with respect to links are as follows :-

-P
find does not dereference symbolic links at all. This is the default behaviour. This option must be specified before any of the file names on the command line.

-H
find does not dereference symbolic links (except in the case of file names on the command line,which are dereferenced). If a symbolic link cannot be dereferenced,the information for the symbolic link itself is used. This option must be specified before any of the file names on the command line.

-L
find dereferences symbolic links where possible,and where this is not possible it uses the properties of the symbolic link itself. This option must be specified before any of the file names on the command line. Use of this option also implies the same behaviour as the -noleaf option. If you later use the -H or -P options,this does not turn off -noleaf.

-follow
This option forms part of the “expression” and must be specified after the file names,but it is otherwise equivalent to -L. The -follow option affects only those tests which appear after it on the command line. This option is deprecated. Where possible,you should use -L instead.

将查找命令转换为Perl

标准配置附带一个兼容于旧版Unix系统的find2perl实用程序。

$ find2perl . -type f | perl
./file1

我们可以要求文件是纯文件本身或链接到普通文件。

$ find2perl . -follow -type f | perl
./1
./2
./3
./4
./5
./file1

在代码find2perl生成后,默认想要的子传递给find from the File::Find module就是

sub wanted {
    my ($dev,$ino,$mode,$nlink,$uid,$gid);

    (($dev,$gid) = lstat($_)) &&
    -f _
    && print("$namen");
}

但随着 – 随后,我们得到

sub wanted {
    my ($dev,$gid) = stat($_)) &&
    -f _
    && print("$namen");
}

请注意,唯一的区别是是否需要通话statlstat,后者被记录为

lstat EXPR
lstat

Does the same thing as the 07003 function (including setting the special _ filehandle) but stats a symbolic link instead of the file the symbolic link points to. If symbolic links are unimplemented on your system,a normal 07003 is done. For much more detailed information,please see the documentation for 07003.

If EXPR is omitted,stats $_.

当find2perl的示例输出显示时,您可以使用filetest运算符表达您的意图,但要准确地说明您选择stat对lstat的符号链接的语义。

有趣的_令牌

上述快速解决方案的末尾是lstat documentation提到的特殊文件句柄。它持有stat或lstat的最新结果的副本,以避免不必重复进行昂贵的系统调用。 -00,如-f,-r,-e和-l也填写这个缓冲区:

If any of the file tests (or either the stat or lstat operator) is given the special filehandle consisting of a solitary underline,then the stat structure of the previous file test (or stat operator) is used,saving a system call. (This doesn’t work with -t,and you need to remember that lstat and -l leave values in the stat structure for the symbolic link,not the real file.) (Also,if the stat buffer was filled by an lstat call,-T and -B will reset it with the results of stat _). Example:

06005

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读