2009-04-08 61 views
40

我最近編寫了一個新的Perl腳本來殺死基於進程名/用戶名的進程,並使用Classes擴展它,以便我可以在其他程序中重新使用進程代碼。我目前的佈局是 -我的Perl腳本如何在同一目錄中找到它的模塊?

/home/mutew/src/prod/pskill  <-- Perl script 
/home/mutew/src/prod/Process.pm <-- Package to handle process descriptions 

我在$ PATH變量中加入了〜/ src/prod來從任何地方訪問腳本。從其駐留目錄以外的任何目錄運行腳本會導致「無法在@INC中定位Process.pm」(考慮到除了/ usr中的共享目錄以外,@INC僅包含當前目錄 - '')。我一直在使用的一種解決方法是使用lib指令,因爲 -

use lib '/home/mutew/src/prod'; 

但這是一個主要的可移植性問題。任何解決方案,這也將允許我將腳本導出到其他系統,而無需更改?


編輯

  1. 我選擇了 'depesz' 的答案,因爲它的簡單性和核心模塊的使用正確的。
  2. brian d foy的答案雖然提出了其他方法來完成同樣的工作(TMTOWTDI),但他在perlfaq8中的貢獻使這個問題變得絕對多餘。
+0

也許這只是我的安裝,但如果兩個文件都在同一個目錄中,我只需「使用FILENAME.pm」即可。然後「我的$ newVar = PACKAGENAME-> new();」用於任何對象編程。 – 2011-05-25 22:29:56

+0

哇,這應該比perl更容易!讓輕鬆的事情變得簡單等。 – 2016-07-16 05:13:03

回答

42

我發現它使用FindBin模塊最簡單的方法。就像這樣:

use FindBin; 
use lib $FindBin::Bin; 

一般來說,我喜歡有這樣的方式提供我的腳本程序是什麼/ bin,然後庫在任何/ lib目錄

在這種情況下,我用一個稍微複雜做法:

use Cwd qw(abs_path); 
use FindBin; 
use lib abs_path("$FindBin::Bin/../lib"); 

的絕對路徑調用是使@INC包含任何/ lib目錄,而不是什麼/ bin中/../ lib中 - 它只是一個微小的變化,但使閱讀的錯誤信息更容易。

+3

不要忘記,abs_path在污染模式下返回污染的結果。你必須使用`use lib(abs_path(「$ FindBin :: Bin /../ lib」)=〜m {^(/.*)})[0];或者只使用`use lib'$ FindBin :: Bin /../ lib「;`因爲沒有理由封裝路徑。 – 2009-04-08 16:23:11

3

看看Par::Packer。它創建一個可執行文件,包含所有腳本的依賴關係。它使分發變得容易。您還可以爲您的用戶提供可安裝在其系統上的模塊版本。查看Module::Starter可輕鬆構建制作標準CPAN樣式分發所需的所有文件。

9

perlfaq8,它回答"How do I add a directory to my include path (@INC) at runtime?"。關於這個問題還有其他幾個問題的答案。


如何在運行時向包含路徑(@INC)添加目錄?

下面是修改的建議方法include路徑,包括環境變量,運行時開關,並在代碼語句:

的PERLLIB環境變量

$ export PERLLIB=/path/to/my/dir 
$ perl program.pl 

的PERL5LIB環境變量

$ export PERL5LIB=/path/to/my/dir 
$ perl program.pl 

perl的-Idir命令行標記

$ perl -I/path/to/my/dir program.pl 

使用lib用法:

use lib "$ENV{HOME}/myown_perllib"; 

最後是特別有用,因爲它知道機器相關的架構。 lib.pm實用模塊首次包含在5.002版本的Perl中。

+0

我在同一天晚些時候閱讀perlfaq8,並在您的貢獻文章中找到了我需要的答案。我想知道你爲什麼包含第二種方法(使用Cwd),因爲@INC已經有了一個當前目錄的條目 - '。' – aks 2009-04-09 16:01:56

0

要將相對鏈接轉換爲絕對並添加到@INC,我通常使用ex :: lib。當然,只有當您打算在計劃運行腳本的所有機器上保持腳本和模塊的相對位置相同時,這纔是有用的。

38

我很好奇,爲什麼簡單的解決方案

use File::Basename; 
use lib dirname (__FILE__); 
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule; 

沒上來。 FindBin模塊似乎有一些問題,如果該文件不是主要的可執行Perl腳本,但只是一個不可執行的Perl模塊。至少我這樣解釋documentation中的評論。沒有真正測試它。

爲了有任何其他的路徑相對於此的Perl文件的位置,這樣做

use File::Basename; 
use lib dirname (__FILE__) . "/MyModules"; 
+3

我很喜歡這種方法 - 我只是不得不使用`使用Cwd qw(abs_path);使用lib dirname(abs_path(__ FILE __));`使腳本通過符號鏈接進行調用。乾杯! – sdaau 2013-01-20 12:30:36

-1

FindBin::libs會找到你所有的庫放置在相對於從您的腳本運行所在的路徑合理的地方。

-1

只是保持簡單。無需導入任何庫;只是找出你當前的工作目錄:

use lib "$ENV{PWD}/relativ_path_own_perllib"; 

對於類似的問題,你可以讀出環境變量,給你關於你身在何處的信息,你的主目錄,操作系統的東西,等等,只有一個一排編程代碼在shell-terminal中,如:

perl -e 'map { print; print " : ". $ENV{$_}." \n\r"; } sort keys %ENV ' 

沒有必要綁定一些庫;只需使用%ENV-Hash即可。

0

您可以使用-I標誌使Perl在任何目錄中查找。在這裏,-I代表@INC,它是perl尋找模塊的路徑數組。使用-I將給定路徑添加到@INC陣列以執行此操作。

如:

​​

,其中lib包含了我要使用的模塊。

我知道這適用於perl 5。我不確定其他版本。

相關問題