我有Perl脚本,需要在执行期间确定脚本的完整路径和文件名.我发现,根据你调用脚本的方式$0
不同而有时包含fullpath+filename
,有时只是filename
.因为工作目录也可以变化,所以我想不出可靠地获取fullpath+filename
脚本的方法.
有人有解决方案吗?
有几种方法:
$0
是当前正在执行的脚本,由POSIX提供,相对于当前工作目录,如果脚本位于CWD或其下方
此外,cwd()
,getcwd()
并abs_path()
通过所提供的Cwd
模块,并告诉你的脚本是从运行
该模块FindBin
提供的$Bin
&$RealBin
变量通常是执行脚本的路径; 该模块还提供$Script
与$RealScript
那些脚本的名称
__FILE__
是Perl解释器在编译期间处理的实际文件,包括其完整路径.
我已经看到的前三个($0
,该Cwd
模块和FindBin
模块)下失效mod_perl
壮观,产生毫无价值输出诸如'.'
或空字符串.在这样的环境中,我使用__FILE__
并使用File::Basename
模块从中获取路径:
use File::Basename; my $dirname = dirname(__FILE__);
$ 0通常是您的程序的名称,那么这个怎么样?
use Cwd 'abs_path'; print abs_path($0);
在我看来这应该工作,因为abs_path知道你是使用相对路径还是绝对路径.
更新对于今年阅读的任何人,您应该阅读下面的Drew的答案.它比我好多了.
Use File::Spec; File::Spec->rel2abs( __FILE__ );
http://perldoc.perl.org/File/Spec/Unix.html
我认为您正在寻找的模块是FindBin:
#!/usr/bin/perl use FindBin; $0 = "stealth"; print "The actual path to this is: $FindBin::Bin/$FindBin::Script\n";
您可以使用FindBin,Cwd,File :: Basename或它们的组合.它们都在Perl IIRC的基础版本中.
我过去使用过Cwd:
CWD:
use Cwd qw(abs_path); my $path = abs_path($0); print "$path\n";
获得绝对的路径$0
或者__FILE__
是你想要的.唯一的麻烦是如果某人做了a chdir()
而且$0
是亲戚 - 那么你需要获得绝对路径BEGIN{}
以防止任何意外.
FindBin
尝试更好地去做一个$PATH
与之相匹配的东西basename($0)
,但有时会做出太令人惊讶的事情(特别是:当cwd中的文件"在你面前"时.)
File::Fu
有File::Fu->program_name
与File::Fu->program_dir
此.
一些简短的背景:
不幸的是,Unix API没有提供带有可执行文件完整路径的正在运行的程序.事实上,执行你的程序可以在字段中提供它想要的任何东西,通常告诉你的程序它是什么.正如所有答案所指出的那样,有各种启发式方法可以找到可能的候选人.但是,搜索整个文件系统总是有效,即使移动或删除可执行文件,也会失败.
但是你不需要Perl可执行文件,它是实际运行的,但是它正在执行的脚本.Perl需要知道脚本在哪里找到它.它存储这__FILE__
,而$0
从Unix的API.这仍然是一个相对路径,所以采取马克的建议并将其封装File::Spec->rel2abs( __FILE__ );
你有没有尝试过:
$ENV{'SCRIPT_NAME'}
要么
use FindBin '$Bin'; print "The script is located in $Bin.\n";
这实际上取决于它是如何被调用的,如果它是CGI还是从普通的shell运行,等等.
为了获得包含我脚本的目录的路径,我使用了已经给出的答案组合.
#!/usr/bin/perl use strict; use warnings; use File::Spec; use File::Basename; my $dir = dirname(File::Spec->rel2abs(__FILE__));