Perl使用FindBin模块解决脚本中的路径问题


在日常的编写过程中,都会将相似的功能作为一个模块方式来使用,这样可以减少代码量、提供代码重用、可读性更高。同样在脚本中需要载入这些功能模块,有三种方法可以实现此类功能,请参考:理解use_require_do使用方法
当然这也会有一些问题:在脚本里需要指出这些功能模块的具体位置(除非你将自己所编写的模块放在@INC路径中,或与脚本的同级目录下),在调用脚本时会因为当前路径不同而导致找不到模块的问题,尤其是在crontab中。
常用的解决方法是,在脚本头部指定位置:
BEGIN {
push (@INC,'/var/www.freeoa.net/libs');
}
或者
BEGIN {
unshift @INC,'/var/www.freeoa.net/libs';
}
亦或
use lib '/var/www.freeoa.net/libs';
使用绝对路径比较麻烦,如果将程序迁移到另外的安装目录,就需要去更改所有的脚本。而直接在use lib中使用相对路径,如'use lib ‘../lib’;'则有很好解决办法,但这需要在特定的目录执行脚本,像在crontab里就也会找不到模块了。
所以最好是让脚本在运行时找到其目录的路径,然后通过相对路径找到lib目录。核心模块FindBin就具备这样的功能,解决执行时模块路径问题。
use FindBin qw($Bin);
use lib "$Bin/../lib";
FindBin导出标量有:
$Bin--path to bin directory from where script was invoked
$Script--basename of script from which perl was invoked
$RealBin--$Bin with all links resolved
$RealScript--$Script with all links resolved
比如我的脚本的路径在/home/hto/bin/myscript.pl
$Bin就应对应:/home/hto/bin/
$Script对应:myscript.pl
告诉Perl在脚本的目录中查找模块,请使用以下命令:
use FindBin [VERSION] qw( $RealBin );
use lib $RealBin;
或
use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path($0));
Setting PERL5LIB at runtime will not affect Perl's search path. You need to export the variable before executing the interpreter.
Alternatively you can modify @INC at compile time (also possible to do in a separate script/module):
BEGIN { unshift @INC, "/path/to/dir" }
参考文档:
FindBin
当然这也会有一些问题:在脚本里需要指出这些功能模块的具体位置(除非你将自己所编写的模块放在@INC路径中,或与脚本的同级目录下),在调用脚本时会因为当前路径不同而导致找不到模块的问题,尤其是在crontab中。
常用的解决方法是,在脚本头部指定位置:
BEGIN {
push (@INC,'/var/www.freeoa.net/libs');
}
或者
BEGIN {
unshift @INC,'/var/www.freeoa.net/libs';
}
亦或
use lib '/var/www.freeoa.net/libs';
使用绝对路径比较麻烦,如果将程序迁移到另外的安装目录,就需要去更改所有的脚本。而直接在use lib中使用相对路径,如'use lib ‘../lib’;'则有很好解决办法,但这需要在特定的目录执行脚本,像在crontab里就也会找不到模块了。
所以最好是让脚本在运行时找到其目录的路径,然后通过相对路径找到lib目录。核心模块FindBin就具备这样的功能,解决执行时模块路径问题。
use FindBin qw($Bin);
use lib "$Bin/../lib";
FindBin导出标量有:
$Bin--path to bin directory from where script was invoked
$Script--basename of script from which perl was invoked
$RealBin--$Bin with all links resolved
$RealScript--$Script with all links resolved
比如我的脚本的路径在/home/hto/bin/myscript.pl
$Bin就应对应:/home/hto/bin/
$Script对应:myscript.pl
告诉Perl在脚本的目录中查找模块,请使用以下命令:
use FindBin [VERSION] qw( $RealBin );
use lib $RealBin;
或
use Cwd qw( abs_path );
use File::Basename qw( dirname );
use lib dirname(abs_path($0));
Setting PERL5LIB at runtime will not affect Perl's search path. You need to export the variable before executing the interpreter.
Alternatively you can modify @INC at compile time (also possible to do in a separate script/module):
BEGIN { unshift @INC, "/path/to/dir" }
参考文档:
FindBin