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

发布于 2024-10-14 10:42:32 字数 195 浏览 5 评论 0原文

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

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

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

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

I'm looking for a way to get two pieces of information:

  • The full path of where a script resides including its filename
  • The full path of where a script was executed from

I know you can use $0 to get the file name, but are there any other reserved variables that are native to Perl that will give me what I'm looking for?

I'd rather not use any special modules, but if it is the only way, then so be it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

太阳哥哥 2024-10-21 10:42:32

使用 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

Using FindBin and Cwd:

#!/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

Sample output (script saved as /tmp/test.pl):

alanhaggai@love:/usr/share$ /tmp/test.pl 
Full path to script: /tmp/test.pl
Executed from path:  /usr/share
冷心人i 2024-10-21 10:42:32
use File::Spec;

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

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

use File::Spec;

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

prints full path to your script including filename as you want.

枕头说它不想醒 2024-10-21 10:42:32

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

the PWD environment variable holds the current working directory, which should be the path the script was executed from.

You can derive the full path of the script with $ENV{PWD} and $0

Edit: providing sample code since it is hard for some to believe this is possible:

I may not have caught all the possible cases, but this should get very close:

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";

Output from test runs:

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
玉环 2024-10-21 10:42:32

这可以通过内置的 $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";

This is available with the built-in $FindBin::Bin variable (see 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";
梦在夏天 2024-10-21 10:42:32

您询问了特殊的 Perl 内容,但没有人提到 __FILE__。检查 perldata 以获得更多信息。当我有文件/脚本/模块的相关子树时,我经常使用这个习惯用法 -

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, $/;

You asked about special Perl stuff and no one has mentioned __FILE__. Check perldata for it and more. I use this idiom often when I have a related subtree of files/scripts/modules–

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, $/;
早茶月光 2024-10-21 10:42:32

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

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

# Look for modules in the same dir as the script.
use lib dirname(realpath($0));

For an solution that also handles symlinks,

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

# Look for modules in the same dir as the script.
use lib dirname(realpath($0));
浅听莫相离 2024-10-21 10:42:32

您可以使用核心 Cwd 模块来获取脚本被执行,核心 File::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";

You can use the core Cwd module to get the directory from which the script was executed, and the core File::Spec module to find the whole path to the script:

#!perl

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

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

print "Script: " . File::Spec->rel2abs($0) . "\n";
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文