Perl - 我可以获得与脚本所在位置以及脚本执行位置相关的路径吗?

Che*_*eso 5 directory perl filenames path reserved-words

我正在寻找获得两条信息的方法:

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

我知道你可以$0用来获取文件名,但是有任何其他保留的Perl原生变量会给我我想要的东西吗?

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

Ala*_*avi 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
Run Code Online (Sandbox Code Playgroud)

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

alanhaggai@love:/usr/share$ /tmp/test.pl 
Full path to script: /tmp/test.pl
Executed from path:  /usr/share
Run Code Online (Sandbox Code Playgroud)


cam*_*cam 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";
Run Code Online (Sandbox Code Playgroud)

测试运行的输出:

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
Run Code Online (Sandbox Code Playgroud)

  • `$PWD` 包含脚本的当前工作目录,而不是脚本的位置。例如,我的 cwd 可能是“~”,但脚本可能位于“/usr/bin”中。 (4认同)
  • @cam:这确实回答了问题的第二部分——脚本是从哪里执行的。但是,这不能用于查找脚本位置的路径。删除最后一句。 (2认同)