Ruby hat drei Möglichkeiten, uns den Namen des aufgerufenen Skripts zu geben:
#!/usr/bin/env ruby
puts "$0 : #{$0}"
puts "__FILE__ : #{__FILE__}"
puts "$PROGRAM_NAME : #{$PROGRAM_NAME}"
Das Speichern dieses Codes als "test.rb" und das Aufrufen auf verschiedene Arten zeigt, dass das Skript den Namen erhält, wie er vom Betriebssystem an ihn übergeben wurde. Ein Skript weiß nur, was das Betriebssystem sagt:
$ ./test.rb
$0 : ./test.rb
__FILE__ : ./test.rb
$PROGRAM_NAME : ./test.rb
$ ~/Desktop/test.rb
$0 : /Users/ttm/Desktop/test.rb
__FILE__ : /Users/ttm/Desktop/test.rb
$PROGRAM_NAME : /Users/ttm/Desktop/test.rb
$ /Users/ttm/Desktop/test.rb
$0 : /Users/ttm/Desktop/test.rb
__FILE__ : /Users/ttm/Desktop/test.rb
$PROGRAM_NAME : /Users/ttm/Desktop/test.rb
Wenn Sie es ~
im zweiten Beispiel mit der Verknüpfung für $ HOME aufrufen, wird es vom Betriebssystem durch den erweiterten Pfad ersetzt, der mit dem im dritten Beispiel übereinstimmt. In allen Fällen ist es das, was das Betriebssystem übergeben hat.
Das Verknüpfen mit der Datei über Hard- und Softlinks zeigt ein konsistentes Verhalten. Ich habe einen harten Link für test1.rb und einen weichen Link für test2.rb erstellt:
$ ./test1.rb
$0 : ./test1.rb
__FILE__ : ./test1.rb
$PROGRAM_NAME : ./test1.rb
$ ./test2.rb
$0 : ./test2.rb
__FILE__ : ./test2.rb
$PROGRAM_NAME : ./test2.rb
Das Starten ruby test.rb
mit einer der Variationen des Skriptnamens liefert konsistente Ergebnisse.
Wenn Sie nur den aufgerufenen Dateinamen möchten, können Sie die File- basename
Methode mit einer der Variablen verwenden oder das Trennzeichen aufteilen und das letzte Element übernehmen.
$0
und __FILE__
haben einige kleine Unterschiede, aber für einzelne Skripte sind sie gleichwertig.
puts File.basename($0)
Es gibt einige Vorteile , die zu verwenden File.basename
, File.extname
und File.dirname
Suite von Methoden. basename
Nimmt einen optionalen Parameter, der die zu entfernende Erweiterung ist. Wenn Sie also nur den Basisnamen ohne die Erweiterung benötigen
File.basename($0, File.extname($0))
tut es, ohne das Rad neu zu erfinden oder sich mit variabler Länge oder fehlenden Verlängerungen oder der Möglichkeit des falschen Abschneidens von Verlängerungsketten " .rb.txt
" befassen zu müssen, zum Beispiel:
ruby-1.9.2-p136 :004 > filename = '/path/to/file/name.ext'
=> "/path/to/file/name.ext"
ruby-1.9.2-p136 :005 > File.basename(filename, File.extname(filename))
=> "name"
ruby-1.9.2-p136 :006 > filename = '/path/to/file/name.ext' << '.txt'
=> "/path/to/file/name.ext.txt"
ruby-1.9.2-p136 :007 > File.basename(filename, File.extname(filename))
=> "name.ext"
Diese Antwort könnte etwas spät kommen, aber ich hatte das gleiche Problem und die akzeptierte Antwort schien mir nicht ganz zufriedenstellend zu sein, also habe ich etwas weiter nachgeforscht.
Was mich störte, war die Tatsache, dass die richtigen Informationen darüber, was der Benutzer eingegeben hatte, nicht wirklich vorhanden waren
$0
oder$PROGRAM_NAME
nicht . Wenn sich mein Ruby-Skript in einem PATH-Ordner befindet und der Benutzer den Namen der ausführbaren Datei eingibt (ohne Pfaddefinitionen wie oder ), wird es immer auf den Gesamtpfad erweitert../script
/bin/script
Ich dachte, dies sei ein Ruby-Defizit, also versuchte ich dasselbe mit Python und zu meinem Leidwesen dort war es nicht anders.
Ein Freund schlug mir einen Hack vor, um nach dem
real thing
In zu suchen/proc/self/cmdline
, und das Ergebnis war:[ruby, /home/danyel/bin/myscript, arg1, arg2...]
(durch das Nullzeichen getrennt). Der Bösewicht hier istexecve(1)
der, der den Pfad zum Gesamtpfad erweitert, wenn er an einen Dolmetscher weitergegeben wird.Beispiel C Programm:
Ausgabe: `Verwendung: / home / danyel / bin / myscript DATEI ...
Um zu beweisen, dass dies tatsächlich eine
execve
Sache ist und nicht von Bash, können wir einen Dummy-Interpreter erstellen, der nichts anderes tut, als die an ihn übergebenen Argumente auszudrucken:Wir kompilieren es und legen es in einem Pfadordner ab (oder legen den vollständigen Pfad nach dem Shebang ab) und erstellen ein Dummy-Skript in
~/bin/myscript/
Nun, in unserer main.c:
Kompilieren und Ausführen
./main
: Interpreter / home / danyel / bin / myscript -v /var/log/apache2.logDer Grund dafür ist wahrscheinlich, dass , wenn das Skript in Ihrer PATH ist und der vollständige Pfad wurde nicht zur Verfügung gestellt, der Dolmetscher dies als erkennen würde
No such file
Fehler, der es tut , wenn Sie tun:ruby myrubyscript --options arg1
und du bist nicht im Ordner mit diesem Skript .quelle
Verwenden Sie
$0
oder$PROGRAM_NAME
, um den Dateinamen abzurufen, der gerade ausgeführt wird.quelle
/usr/local/bin/myScript
und/usr/local/bin
in meinem$PATH
bin und nurmyScript
/usr/local/bin/myScript
$0
$0.split("/").last
?./myScript
, möchte ich eine Variable, die mir gibt./myScript
. Wenn sie tippten/usr/bin/local/myScript
, möchte ich genau das. usw.Dies ist keine Antwort auf Ihre Frage, aber es klingt, als würden Sie ein Rad neu erfinden. Schauen Sie sich die Optparse- Bibliothek an. Sie können damit Befehlszeilenschalter, Argumente usw. definieren und das ganze schwere Heben für Sie erledigen.
quelle