【问题标题】:Is there any equivalent of `pwd -L` in perl?perl中是否有任何等效的`pwd -L`?
【发布时间】:2022-01-07 16:55:54
【问题描述】:

perl 中是否有相当于 shell 的“pwd -L”?

我想要符号链接未解析的当前工作目录?

我当前的工作目录是“/path1/dir1/dir2/dir3”,这里的 dir1 是指向 test1/test2 的符号链接。我希望通过 perl 脚本将当前工作目录设为“/path1/dir1/dir2/dir3”。我得到的是/path1/test1/test2/dir2/dir3。

如何让当前工作目录成为没有符号链接的路径?换句话说,我想实现shell的pwd -L

【问题讨论】:

  • $ENV{PWD} 呢?
  • 你试过Cwd吗?

标签: perl symlink pwd


【解决方案1】:

尝试仅使用 perl 复制 bashpwd 内置函数的行为(特别是在 Path::Tiny 和核心 Cwd 模块的帮助下):

首先,来自help pwdbash 外壳中:

  • -L 如果$PWD 命名为当前工作目录,则打印其值
  • -P 打印物理目录,不带任何符号链接

pwd(1) 的 GNU coreutils 版本还读取 PWD 环境变量以实现 -L,这就是为什么使用 qx// 运行它的原因,即使它无法访问 shell 的内部变量保持跟踪工作目录和路径)

$ pwd -P # First, play with absolute path with symlinks resolved
/.../test1/test2/dir2/dir3
$ perl -MCwd -E 'say getcwd'
/.../test1/test2/dir2/dir3
$ perl -MPath::Tiny -E 'say Path::Tiny->cwd'
/.../test1/test2/dir2/dir3
$ pwd -L # Using $PWD to preserve the symlinks
/.../dir1/dir2/dir3
$ /bin/pwd -L
/.../dir1/dir2/dir3
$ PWD=/foo/bar /bin/pwd -L # Try to fake it out
/.../test1/test2/dir2/dir3
$ perl -MPath::Tiny -E 'my $pwd = path($ENV{PWD}); say $pwd if $pwd->realpath eq Path::Tiny->cwd'
/.../dir1/dir2/dir3

作为一个函数(添加了一些检查,因此它可以处理缺少的 $PWD 环境变量或指向不存在路径的变量):

#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use Path::Tiny;

sub is_same_file ($$) {
    my $s1 = $_[0]->stat;
    my $s2 = $_[1]->stat;
    return $s1->dev == $s2->dev && $s1->ino == $s2->ino;
}

sub get_working_dir () {
    my $cwd = Path::Tiny->cwd;
    # $ENV{PWD} must exist and be non-empty
    if (exists $ENV{PWD} && $ENV{PWD} ne "") {
        my $pwd = path($ENV{PWD});
        # And must point to a directory that is the same filesystem entity as cwd
        return $pwd->is_dir && is_same_file($pwd, $cwd) ? $pwd : $cwd;
    } else {
        return $cwd;
    }
}

say get_working_dir;

【讨论】:

    【解决方案2】:

    使用 perl 反引号运算符在您的系统上运行 pwd -L 命令并将输出捕获到变量中,这适用于我的系统:

     perl -e 'chomp( my $pwdl = `pwd -L` ); print "$pwdl\n";'
    

    【讨论】:

    • 该命令将返回尾随"\n",因此您无需再添加一个
    • 也就是说,Perl 的反引号与 shell 不同,不会去除尾随的换行符。
    • 也就是说$pwdl 实际上并不包含(仅)路径,所以我修复了它。
    猜你喜欢
    • 2010-12-27
    • 2010-12-30
    • 2019-10-29
    • 2015-12-06
    • 1970-01-01
    • 2021-04-22
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    相关资源
    最近更新 更多