A linha Shebang com '#! / usr / bin / env --argument' falha no Linux

46

Eu tenho um script simples:

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

Na minha caixa OSX, ele funciona bem:

osx% ./script.rb
hi

No entanto, na minha caixa linux, isso gera um erro

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

Se eu executar manualmente a linha shebang, tudo funcionará bem

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

Mas posso replicar o erro se empacotar ruby --verbose em um único argumento para env

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

Portanto, acho que isso é um problema de como env está interpretando a redefinição da linha shebang. Estou usando 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.

Isso parece muito estranho. Este é um problema comum com esta versão do env , ou há algo mais acontecendo aqui que eu não saiba?

    
por rampion 06.02.2013 / 21:15

2 respostas

40

Parece que isso acontece porque o Linux (ao contrário do BSD) apenas passa um único argumento para o comando shebang (neste caso, env).

Isso foi amplamente discutido no StackOverflow .

    
por 06.02.2013 / 21:25
3

Encontrou este comentário via @rampion:

What happens is that the kernel processes the first two characters of the file looking for #!. If those are found then it skips all space characters looking for a non-space character and extracts the interpreter path which must be a real executable and not another script, although linux extends that to allow recursive script processing. Having found that then it skips to the first non-space character where it takes from there to the next newline character and passes that as a single argument to the command. There is no 'shell' processing of quotes or other meta characters. It is all very simple and brute force. Therefore you cannot get fancy with options there. You get exactly one argument white space included and 'perl -w' is what the kernel sees here and passes on.

Fonte: link

    
por 09.03.2017 / 11:26