2009-04-08 17 views
40

Kısa bir süre önce süreç adı/kullanıcı adına dayalı işlemleri sonlandırmak için yeni bir Perl komut dosyası yazdım ve diğer programlarda işlem kodunu yeniden kullanabilmem için Classes kullanarak genişlettim. Benim şu anki düzenidir - Perl betiğimin modülü aynı dizinde nasıl bulunur?

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

ben her yerden senaryoyu erişmek için benim $ PATH değişkeninde ~/src/eşya eklendi. Komut dosyası, yerleşik dizini dışındaki herhangi bir dizinden çalıştırılınca, "@Chinde Process.pm'yi bulamıyor" (/ usr, @INC içindeki paylaşılan dizinler dışında yalnızca geçerli dizini içerdiğinden anlaşılabilir) ''). Ben kullanıyorum bir geçici çözüm olarak bu yüzden kullanımı lib yönergesidir -

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

ama bu büyük taşınabilirlik konudur. Ayrıca, betiği diğer sistemlere aktarmadan değiştirip değiştirmemize izin verecek herhangi bir çözüm var mı?


DÜZENLEME nedeniyle basitliği ve çekirdek modülü kullanım doğru olarak 'depesz' cevabını tercih

  1. .
  2. brian d foy'un yanıtı, aynı (TMTOWTDI) başarmak için başka yöntemler önermektedir, perlfaq8'deki katkısı bu soruyu kesinlikle gereksiz kılar.
+0

belki de benim kurulumumdur, ancak her iki dosya aynı dizinde bulunuyorsa sadece "FILENAME.pm kullanın". Sonra "$ newVar = PACKAGENAME-> new();" herhangi bir nesne programlaması için. –

+0

Vay bu Perl'den bundan daha kolay olmalı! Kolay şeyleri daha kolay hale getirin. –

cevap

42

FindBin modülünü kullanmak için bulduğum en basit yaklaşım. Şunun gibi:

use FindBin; 
use lib $FindBin::Bin; 

Genellikle ben programları ne olursa olsun/bin içindedir şekilde sağlanan benim komut dosyalarını olmasını tercih ve kütüphaneler ben biraz daha karmaşık kullanmak Bu durumlarda

lib ne olursa olsun/içindedir yaklaşım:

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

abs_path çağrı @INC ne olursa olsun/lib içermesi yapmaktır değil, ne olursa olsun/bin /../ lib - sadece hafif bir değişiklik olmakla okuma hata iletileri kolaylaştırır.

+3

Abonenin, taint modundaki lekelenmiş sonucu döndürdüğünü unutmayın. Kullanmanız gerekir lib (abs_path ("$ FindBin :: Bin /../ lib") = ~ m {^ (/.*)}) [0]; 'ya da sadece' lib kullanın '$ FindBin :: Bin /../ lib ";' '' '' '' yolun kanonlaşması için bir sebep yoktur. –

3

Par::Packer'a bakın. Komut dosyasının tüm bağımlılıkları dahilinde bir yürütülebilir dosya oluşturur. Dağıtımı kolaylaştırır. Ayrıca, kullanıcılarınıza kendi sisteminizde kurulabilecek bir modülün sürümünü de sağlayabilirsiniz. Standart bir CPAN stili dağılımı oluşturmak için gereken tüm dosyaları oluşturmanın kolay bir yolu için bkz. Module::Starter.

9

perlfaq8'dan, "How do I add a directory to my include path (@INC) at runtime?" yanıtlarını verir. Bu konuyla ilgili sorular için başka birçok cevap var.


Çalışma zamanında içerme yoluma (@INC) bir dizini nasıl ekleyebilirim?

değişken PERLLIB çevre

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

PERL5LIB ortam değişkeni

: Burada

in-kod tabloları, çalışma zamanı anahtarları ortam değişkenleri içeren include yolunuzun değiştirme önerilen yollar vardır ve
$ export PERL5LIB=/path/to/my/dir 
$ perl program.pl 

perl -Idir komut satırı işareti

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

kullanımı lib pragma: bu makine bağımlısı mimarileri ilgili bildiği için

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

son özellikle yararlıdır. Lib.pm pragmatik modül ilk olarak Perl'in 5.002 sürümü ile dahil edildi.

+0

Daha sonra aynı günde perlfaq8 okudum ve yazdığınız makalede ihtiyacım olan cevabı buldum. İkinci yöntemin (Cwd kullan) neden dahil olduğunu merak ettim, çünkü @INC zaten şu anki dizin için bir girdi var - '.' – aks

0

Göreli bağlantıları mutlak hale getirmek ve @INC'ye eklemek için normalde ex :: lib kullanırım. Tabii ki, bu, yalnızca betiğin göreceli konumlarını ve komut dosyasını çalıştırmayı planladığınız tüm makinelerde aynı modülü tutmayı planlıyorsanız kullanışlıdır. basit bir çözüm

use File::Basename; 
use lib dirname (__FILE__); 
use SomeModuleLocatedInTheSameDirectoryAsThisPerlScriptOrModule; 
kadar gelmedi neden

38

merak ediyorum. Dosyanın ana çalıştırılabilir perl betiği değil, sadece çalıştırılamaz bir Perl modülü olması durumunda FindBin modülü bazı sorunlara sahip gibi görünüyor. En azından ben bu yorumu documentation'da yorumladım. Gerçekten test etmedi.

, bu Perl dosyasının konumuna giden tek yol akrabası senaryonuz çalıştığı yerden yoluna göreceli makul yerlere yerleştirilen tüm kütüphanelerini bulacaksınız

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

Bu yaklaşımı çok beğeniyorum - kullanmam Cwd qw (abs_path); lib betiğini (abs_path (__ FILE __)); 'betiği bir sembolik link üzerinden çevirmek için kullanın. Şerefe! – sdaau

+0

Burada işe yarayan tek cevap, –

+0

harika çalıştı! Bu çalışıyor! –

-1

Sadece basit tutunuz. Herhangi bir kütüphaneye ihtiyaç yoktur; Eğer sadece bir ile, böylece nerede olduğunu hakkında bilgi verir ortam değişkeni, ev dizini, işletim sistemi şeyler ve dışarı okuyabilir, benzer sorunlar için

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

: Sadece Geçerli çalışma dizini öğrenmek programlama kod satırının kabuk-terminali gibi:

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

Bazı kitaplıkları bağlamaya gerek yoktur; Sadece %ENV-Hash kullanın.

+0

'$ ENV {PWD}' sorunu çözmez - tam tersi. Komut dosyasının konumunu değil, kullanıcının çalışma dizinini döndürür. – pipe

0

Perl'i -I bayrağını kullanarak herhangi bir dizinde görüntüleyebilirsiniz. Burada, -I, perllerin modülleri aradığı yollar dizisi olan @INC anlamına gelir. -I kullanmak, bu yürütme için verilen yolu @INC dizisine ekler.

örn: lib kullanmak istediğim modülleri içerir

perl -I lib bin/script.pl 

.

Bunun perl 5 için çalıştığını biliyorum. Diğer versiyonlardan emin değilim.

İlgili konular