2010-12-30 8 views
3

그래서, 내 코드 (Perl 스크립트와 펄 모듈)이 같은 나무에 앉아 'LIB 사용'펄 동적 경로

trunk/ 
    util/ 
    process/ 
    scripts/ 

'의 util'디렉토리, 음, 유틸리티, 그 일을 가지고 '프로세스 /'디렉토리에 있어야합니다. 그들은 다음과 같이 접근합니다 :

"util /"과 같은 수준에있는 한 그 구조는 시작하는 곳을 신경 쓰지 않습니다.
는하지만 '스크립트 /'너무 혼잡 얻고 있었다 결정, 그래서 나는이 작동하지 않는 것을 볼 이제

scripts/scripts1 
    scripts/scripts2 

를 만들었습니다. 'trunk/scripts/scripts1/call_script.pl'스크립트를 실행하고 '/trunk/process/process_script.pl'을 호출하면 'process_script.pl'이 UtilityModule()에서 루틴을 가져 오는 데 실패합니다. FindBin이 반환하는 경로는 최상위 호출 스크립트의 경로입니다.

첫 번째 열 개 등이 관련된 모든 것을 해결하기 내가 생각 방법 :

use lib $path_that_came_from_elsewhere; 

을하지만 펄이 그 FindBin 트릭을 통해 제외 할 좋아하지 않는 무언가가 될 것으로 보인다.

BEGIN {} 블록과 관련된 몇 가지 사항을 시도했지만 실제로 내가하는 일을 잘 모르고 리팩토링을 끝내기 쉽습니다. 그러나 누군가가 이런 유형의 문제에 대한 영리한 통찰력을 가지고 있다면, 이것은 몇 가지 포인트를 얻을 수있는 좋은 기회가 될 것입니다! 당신의 가능한 트렁크의 위치는 어디서든 자신의 경로에 "스크립트"(예 아니오 "는/usr/스크립트/재료/트렁크/스크립트 /"경우가 존재 포함하지 않는 경우

답변

6

lib::abs을 사용해 보셨나요? $FindBin의 기능 (일부 경우에는 제한이있을 수 있음)은 호출자와 관련하여 실행되는 바이너리에 상대적으로 작동한다는 것입니다. LIB는 :: 반면에 복근은에 배치 된 모듈을 기준으로 작동 또한 당신은 또한 같은 globs의를 사용할 수 있습니다.

use lib::abs qw{../modules/*/somelib}; 
1

, 당신은 접근 방법은 여기에 설명 사용할 수 있습니다

How do I use beta Perl modules from beta Perl scripts?

그것은 기본적으로 스크립트의 경로를 분석하는 특별한 라이브러리를 포함하고, 그 경로에 절대의 위치에 @INC을 수정 (예 : 귀하의 경우, 그것은 "/ 접두사/스크립트 /"디렉토리 찾아 "/ 접두사를 추가 스크립트가 "/ prefix/scripts /"가 아니라 "/ prefix/scripts/scripts1"에 있더라도 @INC으로 변경하십시오.

그 라인을 따라 신속하고 더러운 뭔가 당신이 일반적인 라이브러리 일처럼 생각하지 않는 경우 :

# Must be at the very beginning of your scripts 
use Cwd 'abs_path'; 
BEGIN { 
    my $full_path_script_name = abs_path($0); 
    if ($full_path_script_name =~ !^(.+)/scripts/!) { 
     my $prefix = $1; 
     unshift(@INC, "$prefix/../util"); 
    } 
} 
3

use 변장에 BEGIN 블록이다, 그래서 참조 아무것도 시작 시간에 정의되어야한다 게다가. 이것은 모듈 FindBin의 변수의 경우이지만 다른 변수의 경우는 아닙니다. FindBin 나에게 까다로운 것 같다/스크립트/스크립트/스크립트 [12] 모두 스크립트에 대한 올바른 디렉토리를 반환 만들기에 관해서는

# this will fail: $path is not yet defined at BEGIN time 
my $path = '../util'; 
use lib $path; 

# this ought to work 
my $path; 
BEGIN { $path = '../util' } 
use lib $path; 

. 그리고 귀하의 질문은 주제에 대해 아직 모호합니다. 필자가 생각하기에, 모든 스크립트는 scripts/scriptN 디렉토리에 있어야합니다. 이 방법은 ../../util은 항상 올바른 장소로 해결됩니다. 하지만이 사실이 귀하의 사례에 해당하는지 확신 할 수 없습니다.

+0

나는 이것을 사랑한다. –

2

정확한 요구 사항을 충족시키지 않으면 서 하드 코딩없이 로컬 라이브러리를 사용하기 위해이 스 니펫 (source < - 중간 주석)을 자주 사용합니다. 당신은 아마 너무 많은 일을하지 않고도 재봉을 할 수 있습니다.

use Cwd 'abs_path'; 
use File::Basename; 
use lib dirname(abs_path $0); 

NB : perldoc perlvar$0가 포함에서 프로그램의 이름이 실행된다.

0

나는 보통를 조작하는 쉘 스크립트 접두사 명령 (보통이라고 툴체인)를 사용 실행 환경 PERL5LIB.

  • 프로젝트/
    • lib 디렉토리/
    • 폴더의 유틸리티/툴체인
    • 빈/응용 프로그램

툴체인 :

#!/bin/sh 
export PERL5LIB=$PWD/lib:$PERL5LIB 
export PATH=$PWD/util:$PWD/bin:$PATH 
exec $* 

이 스크립트의 제한 사항은 프로젝트 디렉토리에서 항상 호출해야한다는 것입니다.

전화 : 이것이하는 일은는 라이브러리와 실행 스크립트에서 불필요한 use lib path을 제거

% ./util/toolchain application 

. 그것은 실행 환경 (그것이 있어야하는 곳)에 남겨 둡니다. 또한 프로덕션 설치 목적으로 스크립트와 lib를 쉽게 재배치 할 수 있습니다.

0

util에서 lib으로 이름을 변경하려는 경우 perl 패키지 FindBin::libs을 사용할 수 있습니다.

http://metacpan.org/pod/FindBin::libs

그런 다음 당신은 단순히 스크립트의 부모의 디렉토리의 각각에 대해

use FindBin::libs; 
use UtilityModule qw(all); 

말할 수를 참조하십시오, 그것은 lib 하위 디렉토리를 검색하고, 모듈의 위치로 사용됩니다.

귀하의 경우 trunk/scripts/scripts1에있는 스크립트는 모듈에 대해 trunk/scripts/libtrunk/lib을 확인합니다.