5

我正在寻找一种获取两条信息的方法:

  • 脚本所在位置的完整路径,包括其文件名
  • 执行脚本的完整路径

我知道您可以使用它$0来获取文件名,但是是否还有其他 Perl 原生的保留变量可以为我提供所需的内容?

我宁愿不使用任何特殊的模块,但如果这是唯一的方法,那就这样吧。

4

7 回答 7

7

使用FindBinCwd

#!/usr/bin/env perl

use strict;
use warnings;

use Cwd        ();
use FindBin    ();
use File::Spec ();

my $full_path = File::Spec->catfile( $FindBin::Bin, $FindBin::Script );
my $executed_from_path = Cwd::getcwd();

print <<OUTPUT;
Full path to script: $full_path
Executed from path:  $executed_from_path
OUTPUT

示例输出(脚本另存为/tmp/test.pl):

alanhaggai@love:/usr/share$ /tmp/test.pl 
Full path to script: /tmp/test.pl
Executed from path:  /usr/share
于 2011-01-26T21:05:26.883 回答
3
use File::Spec;

print File::Spec->rel2abs($0);

根据需要打印脚本的完整路径,包括文件名。

于 2011-01-26T20:40:41.497 回答
2

环境变量保存当前PWD工作目录,它应该是执行脚本的路径。

$ENV{PWD}您可以使用和导出脚本的完整路径$0

编辑:提供示例代码,因为有些人很难相信这是可能的:

我可能没有抓住所有可能的情况,但这应该非常接近:

use strict;
use warnings;

print "PWD: $ENV{PWD}\n";
print "\$0: $0\n";

my $bin = $0;
my $bin_path;

$bin =~ s#^\./##; # removing leading ./ (if any)

# executed from working directory
if ($bin !~ m#^/|\.\./#) {
  $bin_path = "$ENV{PWD}/$bin";
}
# executed with full path name
elsif ($bin =~ m#^/#) {
  $bin_path = $0;
}
# executed from relative path
else {
  my @bin_path = split m#/#, $bin;
  my @full_path = split m#/#, $ENV{PWD};

  for (@bin_path) {
    next if $_ eq ".";
   ($_ eq "..") ? pop @full_path : push @full_path, $_;
  }
  $bin_path = join("/", @full_path);
}

print "Script Path: $bin_path\n";

测试运行的输出:

PWD: /tmp
$0: ../home/cmatheson/test.pl
Script Path: /home/cmatheson/test.pl

PWD: /home/cam
$0: ./test.pl
Script Path: /home/cam/test.pl

PWD: /usr/local
$0: /home/cam/test.pl
Script Path: /home/cam/test.pl

PWD: /home/cam/Desktop/foo
$0: ../../src/./git-1.7.3.2/../../test.pl
Script Path: /home/cam/test.pl
于 2011-01-26T20:40:02.443 回答
2

这可通过内置的 $FindBin::Bin 变量获得(参见perldoc FindBin):

use FindBin;
use File::Spec;

print "the location of my script is: ", $FindBin::Bin, "\n";
print "the basename of my script is: ", $FindBin::Script, "\n";
print "the full path (symlinks resolved) of my script is: ", File::Spec->catfile($FindBin::RealBin, $FindBin::RealScript), "\n";
于 2011-01-26T20:45:52.603 回答
2

对于也处理符号链接的解决方案,

use Cwd            qw( realpath );
use File::Basename qw( dirname );

# Look for modules in the same dir as the script.
use lib dirname(realpath($0));
于 2011-01-27T08:13:45.097 回答
1

您询问了有关 Perl 的特殊内容,但没有人提及__FILE__。检查perldata以获取更多信息。当我有文件/脚本/模块的相关子树时,我经常使用这个成语–</p>

use Path::Class qw( file );
use File::Spec;

my $self_file = file( File::Spec->rel2abs(__FILE__) );
print
    " Full path: $self_file", $/,
    "Parent dir: ", $self_file->parent, $/,
    " Just name: ", $self_file->basename, $/;
于 2011-01-27T02:51:44.000 回答
0

您可以使用 coreCwd模块获取执行脚本的目录,并使用 coreFile::Spec模块查找脚本的整个路径:

#!perl

use strict;
use warnings;
use Cwd;
use File::Spec;

my $dir = getcwd();
print "Dir: $dir\n";

print "Script: " . File::Spec->rel2abs($0) . "\n";
于 2011-01-26T20:44:27.250 回答