Es gibt einige Möglichkeiten:
$0
ist das aktuell ausgeführte Skript, wie es von POSIX bereitgestellt wird, relativ zum aktuellen Arbeitsverzeichnis, wenn sich das Skript im oder unter dem CWD befindet
- Darüber hinaus
cwd()
, getcwd()
und abs_path()
werden von dem mitgelieferten Cwd
Modul und Ihnen sagen , wo das Skript aus betrieben wird
- Das Modul
FindBin
stellt die $Bin
& $RealBin
Variablen zur Verfügung, die normalerweise den Pfad zum ausführenden Skript darstellen. Dieses Modul bietet auch $Script
& $RealScript
das sind die Namen des Skripts
__FILE__
ist die eigentliche Datei, mit der sich der Perl-Interpreter während der Kompilierung befasst, einschließlich des vollständigen Pfads.
Ich habe gesehen, dass die ersten drei ( $0
, das Cwd
Modul und das FindBin
Modul) mod_perl
spektakulär versagen und wertlose Ausgaben wie '.'
oder eine leere Zeichenfolge erzeugen . In solchen Umgebungen verwende __FILE__
ich den Pfad und erhalte ihn mithilfe des File::Basename
Moduls:
use File::Basename;
my $dirname = dirname(__FILE__);
__FILE__
) nicht ganz wie erwartet funktioniert? Am Ende habe ich den relativen Pfad, von dem aus das Skript ausgeführt wurde, während die akzeptierte Antwort mir den vollständigen absoluten Pfad gibt.dirname(__FILE__)
folgt keinen Symlinks. Wenn Sie also die ausführbare Datei verlinkt haben und hoffen, den Speicherort einer anderen Datei im Installationsspeicherort zu finden, müssen Sie dies überprüfenif( -l __FILE__)
und danndirname(readlink(__FILE__))
.perl -e 'use Module::CoreList; print Module::CoreList->first_release("File::Basename");'; echo
. DafürFile::Basename
war Perl 5.0.0, das Ende der 90er Jahre veröffentlicht wurde - ich denke, es ist jetzt sicher, es zu verwenden.$ 0 ist normalerweise der Name Ihres Programms. Wie wäre es damit?
Mir scheint, dass dies funktionieren sollte, da abs_path weiß, ob Sie einen relativen oder absoluten Pfad verwenden.
Update Für alle, die dies Jahre später lesen, sollten Sie Drews Antwort lesen . Es ist viel besser als meins.
quelle
realpath
, was ein Synonym für istabs_path
, falls Sie den Namen ohne Unterstrich bevorzugenperl -e 'use Cwd "abs_path";print abs_path($0);'
Drucke/tmp/-e
-e
) ausführen , erstellt Perl meiner Meinung nach eine temporäre Datei zum Speichern Ihres Inline-Skripts. Sieht aus wie der Ort in Ihrem Fall ist/tmp
. Was haben Sie erwartet?http://perldoc.perl.org/File/Spec/Unix.html
quelle
Ich denke, das Modul, das Sie suchen, ist FindBin:
quelle
Sie können FindBin , Cwd , File :: Basename oder eine Kombination davon verwenden. Sie sind alle in der Basisdistribution von Perl IIRC enthalten.
Ich habe in der Vergangenheit Cwd verwendet:
Cwd:
quelle
Den absoluten Weg zu
$0
oder zu finden,__FILE__
ist das, was Sie wollen. Das einzige Problem ist, wenn jemand einen gemacht hatchdir()
und der$0
relativ war - dann müssen Sie den absoluten Pfad in a findenBEGIN{}
, um Überraschungen zu vermeiden.FindBin
versucht, besser zu werden und in der Suche$PATH
nach etwas Passendem zu suchenbasename($0)
, aber es gibt Zeiten, in denen dies viel zu überraschende Dinge bewirkt (insbesondere: wenn die Datei im cwd "direkt vor Ihnen" liegt).File::Fu
hatFile::Fu->program_name
undFile::Fu->program_dir
dafür.quelle
chdir()
Kompilierungszeit (dauerhaft) zu arbeiten?Einige kurze Hintergrundinformationen:
Leider bietet die Unix-API kein laufendes Programm mit dem vollständigen Pfad zur ausführbaren Datei. Tatsächlich kann das Programm, das Ihr Programm ausführt, alles bereitstellen, was es in dem Feld möchte, das Ihrem Programm normalerweise sagt, was es ist. Wie alle Antworten zeigen, gibt es verschiedene Heuristiken, um wahrscheinliche Kandidaten zu finden. Die Suche im gesamten Dateisystem funktioniert jedoch immer, und selbst das schlägt fehl, wenn die ausführbare Datei verschoben oder entfernt wird.
Sie möchten jedoch nicht die ausführbare Perl-Datei, die tatsächlich ausgeführt wird, sondern das Skript, das sie ausführt. Und Perl muss wissen, wo sich das Skript befindet, um es zu finden. Es speichert dies in
__FILE__
, während$0
es von der Unix-API stammt. Dies kann immer noch ein relativer Weg sein, also nimm Marks Vorschlag und kanonisiere ihn mitFile::Spec->rel2abs( __FILE__ );
quelle
__FILE__
gibt mir immer noch einen relativen Weg. dh '.'.Hast du es versucht:
oder
Es hängt wirklich davon ab, wie es aufgerufen wird und ob es CGI ist oder von einer normalen Shell usw. ausgeführt wird.
quelle
Um den Pfad zu dem Verzeichnis zu erhalten, das mein Skript enthält, habe ich eine Kombination von bereits gegebenen Antworten verwendet.
quelle
perlfaq8 beantwortet eine sehr ähnliche Frage mit der
rel2abs()
Funktion on$0
. Diese Funktion finden Sie in File :: Spec.quelle
Es müssen keine externen Module verwendet werden. Mit nur einer Zeile können Sie den Dateinamen und den relativen Pfad angeben. Wenn Sie Module verwenden und einen Pfad relativ zum Skriptverzeichnis anwenden müssen, reicht der relative Pfad aus.
quelle
: DD
quelle
Suchst du das?:
Die Ausgabe sieht folgendermaßen aus:
Es funktioniert sowohl unter Windows als auch unter Unix.
quelle
quelle
Das Problem mit
__FILE__
ist, dass der Pfad des Kernmoduls ".pm" gedruckt wird, nicht unbedingt der Skriptpfad ".cgi" oder ".pl", der ausgeführt wird. Ich denke, es hängt davon ab, was Ihr Ziel ist.Es scheint mir, dass
Cwd
nur für mod_perl aktualisiert werden muss. Hier ist mein Vorschlag:Bitte fügen Sie Vorschläge hinzu.
quelle
Ohne externe Module, gültig für Shell, funktioniert auch mit '../' gut:
Prüfung:
quelle
Das Problem bei der Verwendung
dirname(__FILE__)
ist, dass es keinen Symlinks folgt. Ich musste dies für mein Skript verwenden, um dem Symlink zum tatsächlichen Speicherort der Datei zu folgen.quelle
Alle bibliotheksfreien Lösungen funktionieren nicht auf mehr als ein paar Arten, um einen Pfad zu schreiben (denken Sie an ../ oder /bla/x/../bin/./x/../ usw. Meine Lösung sieht so aus Ich habe eine Besonderheit: Ich habe nicht die geringste Ahnung, warum ich die Ersetzungen zweimal ausführen muss. Wenn ich das nicht tue, bekomme ich ein falsches "./" oder "../". Abgesehen davon scheint mir ziemlich robust zu sein.
quelle
Keine der "Top" -Antworten war richtig für mich. Das Problem bei der Verwendung von FindBin '$ Bin' oder Cwd besteht darin, dass sie den absoluten Pfad zurückgeben, wobei alle symbolischen Links aufgelöst sind. In meinem Fall brauchte ich den genauen Pfad mit vorhandenen symbolischen Links - genau wie der Unix-Befehl "pwd" und nicht "pwd -P". Die folgende Funktion bietet die Lösung:
quelle
Unter Windows funktionierte die Verwendung von
dirname
undabs_path
zusammen am besten für mich.hier ist der Grund:
quelle
Was ist los mit
$^X
?Würde Ihnen den vollständigen Pfad zur verwendeten Perl-Binärdatei geben.
Evert
quelle
Unter * nix haben Sie wahrscheinlich den Befehl "whereis", der Ihren $ PATH nach einer Binärdatei mit einem bestimmten Namen durchsucht. Wenn $ 0 nicht den vollständigen Pfadnamen enthält, sollten Sie durch Ausführen von whereis $ scriptname und Speichern des Ergebnisses in einer Variablen feststellen, wo sich das Skript befindet.
quelle