Shebang-Zeile mit dem Befehl "#! / Usr / bin / env --argument" schlägt unter Linux fehl

53

Ich habe ein einfaches Skript:

#!/usr/bin/env ruby --verbose
# script.rb
puts "hi"

Auf meiner OSX-Box läuft es einwandfrei:

osx% ./script.rb
hi

Auf meiner Linux-Box wird jedoch ein Fehler ausgegeben

linux% ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

Wenn ich die Shebang-Linie manuell starte, funktioniert es einwandfrei

linux% /usr/bin/env ruby --verbose ./script.rb
hi

Aber ich kann den Fehler replizieren, wenn ich ihn ruby --verbosein ein einziges Argument packeenv

linux% /usr/bin/env "ruby --verbose" ./script.rb
/usr/bin/env: ruby --verbose: No such file or directory

Ich denke, dies ist ein Problem bei der envInterpretation des Zurücksetzens der Shebang-Linie. Ich benutze GNU Coreutils 8.4 env:

linux% /usr/bin/env --version
env (GNU coreutils) 8.4
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Written by Richard Mlynarik and David MacKenzie.

Das scheint wirklich seltsam. Ist dies ein häufiges Problem mit dieser Version von env, oder ist hier noch etwas los, das ich nicht kenne?

Rampion
quelle
4
relevant?
Rampion
Gleiches hier mit coreutils 8.17. Seltsam. Berichterstattung an Fedora, da dies ausdrücklich gegen das im Handbuch Gesagte verstößt.
Vonbrand
@vonbrand Was hat Fedora gesagt? "Es ist uns egal."
Katze

Antworten:

44

Es sieht so aus, als ob Linux (im Gegensatz zu BSD) nur ein einziges Argument an den Befehl shebang übergibt (in diesem Fall env).

Dies wurde ausführlich in StackOverflow erörtert .

Rampion
quelle
3
Siehe auch diese Seite für eine Überprüfung des Verhaltens auf verschiedenen Unices.
Stéphane Chazelas
4
Spezifikation fehlgeschlagen. Mein Gott.
Konrad Rudolph
3
Wenn mit "Spezifikation fehlgeschlagen" gemeint ist, dass alle Unix-Systeme mehr als 1 Argument akzeptieren sollten, dann stimme ich Ihnen zu 100% zu :)
Alexander Mills
Nicht so sehr "Linux" als GNU.
Wille
5

Gefunden über @rampion Kommentar:

Was passiert ist, dass der Kernel die ersten beiden Zeichen der Datei verarbeitet und nach #! Sucht. Wenn diese gefunden werden, überspringt es alle Leerzeichen, die nach einem Nicht-Leerzeichen suchen, und extrahiert den Interpreterpfad, der eine echte ausführbare Datei und kein anderes Skript sein muss, obwohl Linux diese erweitert, um eine rekursive Skriptverarbeitung zu ermöglichen. Nachdem es dies gefunden hat, springt es zum ersten Nicht-Leerzeichen, wo es von dort zum nächsten Zeilenumbruchzeichen übergeht und dieses als einzelnes Argument an den Befehl übergibt. Es gibt keine Shell-Verarbeitung von Anführungszeichen oder anderen Metazeichen. Es ist alles sehr einfach und brachial. Daher kann man sich dort nicht mit Optionen auseinandersetzen. Sie erhalten genau ein Argument Leerraum enthalten und "Perl-w" ist, was der Kernel hier sieht und weitergibt.

Quelle: http://lists.gnu.org/archive/html/bug-sh-utils/2002-04/msg00020.html

Aalex Gabi
quelle