Ausgangslage
Gegeben ein Perl-Projekt myproject mit einem eigenen
Projektverzeichnis PREFIX/myproject und einer Unix-typischen
Unterverzeichnisstruktur mit den Verzeichnissen bin, lib usw.
PREFIX/myproject/bin/myprogram
lib/perl5/MyClass.pm
...
PREFIX ist ein beliebiger Verzeichnis-Pfad. Im Unterverzeichnis
bin sind die Programme des Projektes installiert (hier ein Programm
myprogram) und in Unterverzeichnis lib/perl5 die Module des
Projektes (hier ein Modul MyClass.pm).
Wir wollen das Programm myprogram nun außerhalb des Projektbaums
verfügbar machen, z.B. damit es über einen allgemeinen Suchpfad
aufrufbar ist, oder - falls es ein CGI-Programm ist - um es in eine
Web-Verzeichnisstruktur einzufügen, ohne dass wir einen ScripAlias
definieren können oder wollen.
Problem
Das Problem: Außerhalb des Projektbaums installiert verliert das
Programm den Bezug zum Projektverzeichnis und kann die anderen
Verzeichnisse des Baums, wie z.B. das Modulverzeichnis lib/perl5
nicht ohne Weiteres adressieren. Man könnte den Pfad zum
Projektverzeichnis auf einer Environment-Variablen definieren, aber
das ist umständlich.
Lösung
Ein eleganterer Weg ist, das Programm per Symlink außerhalb des
Projektbaums zu installieren und den realen Installationspfad des
Programms mittels der Variable $RealBin des (Core-)Moduls
FindBin zu ermitteln.
$ ln -s PREFIX/myproject/bin/myprogram /usr/local/bin/myprogram
Am Anfang von myprogram, vor dem Laden des projektspezifischen
Moduls MyClass, fügen wir die beiden Zeilen ein:
use FindBin qw/$RealBin/;
use lib "$RealBin/../lib/perl5";
use MyClass;
Der Pfad $RealBin ist das Verzeichnis, in dem das aufgerufene
Programm sich befindet, und zwar nach Auflösung aller Symlinks. D.h.
der Pfad ist stets
auch wenn das Programm über den Pfad /usr/local/bin/myprogram
aufgerufen wird.