La ligne Shebang avec `#! / Usr / bin / env commande --argument` échoue sous Linux

53

J'ai un script simple:

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

Sur ma machine OSX, ça fonctionne bien:

osx% ./script.rb
hi

Cependant, sur ma machine Linux, cela jette une erreur

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

Si je lance la ligne shebang manuellement, cela fonctionne bien

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

Mais je peux reproduire l'erreur si je compresse ruby --verboseen un seul argumentenv

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

Donc, je pense que c'est un problème avec la façon dont envon interprète la réinitialisation de la ligne shebang. J'utilise 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.

Cela semble vraiment étrange. Est-ce un problème courant avec cette version de envou y a-t-il autre chose que je ne connais pas qui se passe ici?

rampion
la source
4
pertinent?
rampion
Idem ici avec coreutils 8.17. Bizarre. Faire rapport à Fedora, car cela va explicitement à l'encontre de ce que dit le manuel.
vonbrand
@vonbrand Qu'a dit Fedora? "On s'en fiche."
chat

Réponses:

44

On dirait que c'est parce que Linux (contrairement à BSD) ne transmet qu'un seul argument à la commande shebang (dans ce cas, env).

Cela a été longuement discuté sur StackOverflow .

rampion
la source
3
voir aussi cette page pour une revue du comportement de différents Unices.
Stéphane Chazelas
4
La spécification échoue. Mon Dieu.
Konrad Rudolph
3
Si par "spécification échouée", vous voulez dire que tous les systèmes Unix doivent accepter plus d'un argument, je suis 100% d'accord avec vous :)
Alexander Mills
Pas tellement 'linux' que GNU.
sera
5

J'ai trouvé ce commentaire via @rampion:

En fait, le noyau traite les deux premiers caractères du fichier en recherchant # !. Si ceux-ci sont trouvés, tous les caractères de l'espace seront ignorés à la recherche d'un caractère non-espace et le chemin de l'interpréteur sera extrait, ce qui doit être un véritable exécutable et non un autre script, bien que linux l'étende pour permettre le traitement de script récursif. Ayant trouvé cela, il saute au premier caractère sans espace où il va de là au prochain caractère de nouvelle ligne et le transmet en tant qu'argument unique à la commande. Il n'y a pas de traitement "shell" des guillemets ou autres méta-caractères. Tout est très simple et force brute. Par conséquent, vous ne pouvez pas obtenir de fantaisie avec des options là-bas. Vous obtenez exactement un espace blanc d'argument inclus et 'perl -w' est ce que le noyau voit ici et le transmet.

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

Aalex Gabi
la source