如何从相对路径获取Perl程序的绝对路径?

3

我需要找到当前正在运行的Perl脚本的完整路径,例如

  • 对于~/dir/my.pl,我需要它是“/home/user/dir/my.pl”。$0将给我“~/dir/my.pl”。

  • 对于./my.pl,我仍然需要“/home/user/dir/my.pl”

等等。谢谢!

6个回答

6
使用FindBin模块:
$ cat /tmp/foo/bar/baz/quux/prog
#! /usr/bin/perl

use FindBin;

print "$FindBin::Bin/$FindBin::Script\n";

$ PATH=/tmp/foo/bar/baz/quux prog
/tmp/foo/bar/baz/quux/prog

$ cd /tmp/foo/bar/baz/quux

$ ./prog 
/tmp/foo/bar/baz/quux/prog

看起来它给了我一个空的$FindBin :: Bin,尽管 - n-alexander
你是如何运行你的程序的? - Greg Bacon
只需运行./my.pl,其中包含#!/usr/bin/perl。 - n-alexander
FindBin存在已知问题(http://search.cpan.org/~tty/kurila-1.19_0/lib/FindBin.pm#KNOWN_ISSUES),所以你是否遇到了其中之一? - Greg Bacon
1
FindBin存在问题,如果你有/bin/script.pl -> ~/scripts/script.pl,那么在执行script.pl之后,$FindBin::Bin包含的是/bin而不是~/scripts/。你需要使用&File::Basename::dirname($Cwd::realpath($0))来获取脚本的真正父目录。 - Jiri Klouda

5

看起来你正在寻找File::Spec中的rel2abs函数。例如:

#!/usr/bin/perl

use File::Spec;
my $location = File::Spec->rel2abs($0);
print "$location\n";

这将按照您描述的方式解析$0:
$ ./myfile.pl
/Users/myname/myfile.pl
$ ~/myfile.pl
/Users/myname/myfile.pl

或者,您可以以完全相同的方式使用Cwd::abs_path


很遗憾,它不会。这意味着当调用被执行时,您仍然在相同的目录中,但也可能不是这样。 - n-alexander
嗯...不是这样的吗...? `$ export PATH=~/; cd /tmp/; myfile.pl' -> /Users/myname/myfile.pl - Ryan Bright
我的意思是,myfile.pl 是一个复杂的程序,在它被调用之后但在尝试解析路径之前可能已经进行了 cd 操作。然后,如果作为 ./myfile.pl 调用,则会解析为 /newdir/myfile.pl。 - n-alexander

2

1

看起来你只需要将路径扩展为它们的绝对值。查看这篇文章了解如何做到这一点。


除非您知道调用时的当前工作目录(即CWD),否则无法将./my.pl扩展为任何内容。 - n-alexander
这也不处理波浪号扩展。 - brian d foy

0

如果文件本身是符号链接,许多提到的概念都会失效。我通常以以下方式启动我的脚本:

use strict;
use English;
use warnings;

use Cwd qw(realpath);
use File::Basename;
use lib &File::Basename::dirname(&Cwd::realpath($PROGRAM_NAME));

希望这能有所帮助。


0
使用 FindBin 模块

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接