2017-08-29 4 views
1

J'essaie de comprendre comment perl traite de la ligne shebang. Pour penser que tout interpréteur mentionné dans la "position de commande" sur la ligne de commande aurait préséance sur celui mentionné dans la ligne shebang. Par exemple, si un script exécutable appelé demo ressemble à ceciComment Perl gère-t-il la ligne shebang?

#!/usr/local/bin/perl-5.00503 

printf "$]\n"; 

... alors j'observiez les points suivants:

$ ./demo 
5.00503 
% /usr/local/bin/perl-5.22 ./demo 
5.022003 

OIEau, dans la première exécution, l'interprète dans le tralala est le un en cours d'exécution, tandis que dans la seconde c'est celui mentionné sur la ligne de commande. Jusqu'ici tout va bien.

Mais maintenant, si je change le « interprète » sur le tralala à quelque chose comme /usr/bin/wc, il bat toujours tout interprète perl je mentionne sur la ligne de commande:

% cat demo-wc 
#!/usr/bin/wc 

printf "$]\n"; 

% ./demo-wc       # produces the expected behavior 
     4  3  31 ./demo-wc 
% /usr/local/bin/perl-5.22 ./demo-wc 
     4  3  31 ./demo-wc 
% /usr/local/bin/perl-5.14 ./demo-wc 
     4  3  31 ./demo-wc 

AFAICT, ce comportement spécial semble être limité perl interprètes; non perl interprètes, tels que /bin/bash, ne « passer outre » le tralala:

% /bin/bash ./demo-wc 
$] 

L'essentiel est que perl semble avoir radicalement différentes politiques de gestion du tralala en fonction de l'interprète mentionné.


  1. Comment perl déterminer la politique à suivre?
  2. Quelles sont exactement les politiques dans les deux cas?
+1

Déjà répondu ici: https://stackoverflow.com/a/29563961/152948 – hobbs

+1

@hobbs Pas tout à fait, cela répond à une partie de la question. – zdim

Répondre

6

Il existe plusieurs cas différents dans vos tests. Lorsque vous utilisez ./demo..., le noyau trouve le #! dans le nombre magique (les 16 premiers bits) et exécute ce programme, ou passe la ligne au shell s'il échoue, ce qui commence ce qui est dessus.Mais quand vous invoquez un perl sur la ligne de commande, ce binaire est lancé par le shell, puis cet interpréteur perl lui-même traite le shebang. Dans ce cas, il rejette la partie perl mais prend en compte les commutateurs – si la ligne contient "perl".

Si le shebang fait pas invoquer perl, nous avons un comportement spécial à Perl. De perlrun

Si la ligne #! ne contient pas le mot « perl » ni le mot « indir », le programme porte le nom du #! est exécuté au lieu de l'interpréteur Perl. C'est un peu bizarre, mais cela aide les gens sur les machines qui ne le font pas #!, car ils peuvent dire à un programme que leur SHELL est /usr/bin/perl, et Perl enverra alors le programme à l'interpréteur correct pour eux .

1

Contrairement à la plupart des autres interpréteurs, perl effectue son propre traitement de la ligne #!. Cela lui permet de prendre plusieurs arguments d'option, même si le gestionnaire #! du noyau ne transmettra qu'une seule chaîne.

Les détails sont sur la page de manuel perlrun. La partie pertinente pour vous est la suivante:

Si le "#!" ligne ne contient pas le mot "perl" ni le mot "indir" le programme nommé après le "#!" est exécuté à la place de l'interpréteur Perl. C'est un peu bizarre, mais cela aide les gens sur les machines qui ne font pas "#!", Car ils peuvent dire à un programme que leur shell est/usr/bin/perl, et Perl enverra alors le programme à l'interpréteur correct pour leur.