Is there an equivalent of shell's "pwd -L" in perl?
I want the current working directory with symlinks unresolved?
My current working directory is "/path1/dir1/dir2/dir3", and here dir1 is symlink to test1/test2. I want current working directory to be "/path1/dir1/dir2/dir3" via perl script. What I am getting is /path1/test1/test2/dir2/dir3.
How can I get the current working directory to be the path with no symlinks resolved? In other words, I would want to implement shell's pwd -L.
CodePudding user response:
use the perl backtick operator to run the pwd -L command on your system and capture the output into a variable, this works on my system:
perl -e 'chomp( my $pwdl = `pwd -L` ); print "$pwdl\n";'
CodePudding user response:
An attempt to replicate the behavior of bash's pwd builtin using just perl (In particular, with the aid of the Path::Tiny and core Cwd modules):
First, from help pwd in a bash shell:
- -L print the value of
$PWDif it names the current working directory- -P print the physical directory, without any symbolic links
(The GNU coreutils version of pwd(1) also reads the PWD environment variable for its implementation of -L, which is why running it with qx// works even though it doesn't have access to the shell's internal variables keeping track of the working directory and path taken to it)
$ 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
As a function (With some added checks so it can handle a missing $PWD environment var or one that points to a non-existent path):
#!/usr/bin/env perl
use strict;
use warnings;
use feature qw/say/;
use Path::Tiny;
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 whose real path is equal to the cwd
return $pwd->is_dir && $pwd->realpath eq $cwd ? $pwd : $cwd;
} else {
return $cwd;
}
}
say get_working_dir;
