Si je veux exécuter un script bash dont les autorisations d'exécution ne sont pas définies, je peux faire:
bash script.sh
Que devrais-je utiliser à la place de bash
si le script n'est pas exécutable et que je ne connais pas l'interprète correct? Existe-t-il une commande qui recherche l'interprète de la ligne Shebang et exécute le script avec?
Oui. Il s'appelle Perl
:
Perl foo.bash # works
Perl foo.lua # works
Perl foo.clisp # works
Perl foo.csh # works
Perl foo.php # works
Perl foo.gnuplot # works (no arguments)
Perl foo.pl # works (obviously)
Perl foo.py # works
Perl foo.sh # works
Perl foo.tcl # works
Perl foo.rb # works
Perl foo.nodejs # works
Perl foo.r # works
Perl foo.oct # works
Perl foo.csharp # works (no arguments)
Ceci est mentionné dans documentation de Perl :
Si la ligne
#!
ne contient pas le mot "Perl" ni le mot "indir", le programme nommé d'après le#!
est exécuté à la place de l'interpréteur Perl. C'est un peu bizarre, mais cela aide les personnes sur des machines qui ne respectent pas#!
, car elles peuvent dire à un programme que leur shell est/usr/bin/Perl, et Perl enverra ensuite le programme à l'interprète approprié.
Si le script a été exécuté à partir de l'interprète, vous ne pouvez pas être sûr qu'il possède le Shebang du tout . () Les scripts exécutés à partir de l'interprète n'ont pas besoin du Shebang , if vous appelez l'interprète pour exécuter le code.
La réponse est donc non, aucune commande ne permet de savoir avec certitude quelle est la langue (interprète) avec laquelle exécuter le script. Vous pouvez cependant toujours regarder à l'intérieur du script et voir s'il a le Shebang à découvrir.
Les règles en bref:
Si le script n'a pas de Shebang, il n'y a pas d'information (directe *) à l'intérieur du script pour indiquer quel interpréteur utiliser.
Vous pouvez bien sûr toujours écrire un script wrapper pour essayer de savoir si le script contient le Shebang et en lire l'interpréteur, puis l'exécuter à partir du trouvé interprète.
Un exemple
#!/usr/bin/env python3
import subprocess
import sys
args = sys.argv[1:]; script = args[0]
try:
lang = open(script).readlines()[0].replace("#!", "").strip().split()[-1]
cmd = [lang, script]+args[1:]
subprocess.call(cmd)
except (PermissionError, FileNotFoundError, IndexError):
print("No valid Shebang found")
Enregistrez-le sous tryrun
dans $PATH
(par exemple, ~/bin
, créez le répertoire s'il n'existe pas, déconnectez-vous puis reconnectez-vous), rendez-le exécutable . Puis en cours d'exécution:
tryrun /path/to/nonexecutablescript
appelle (testé) l'interprète correct sur mes scripts python
et bash
non exécutables.
#!
et utilise le reste pour appeler l'interpréteur.PermissionError
ou un FileNotFoundError
name__.L'extension (.sh
, .py
etc.) ne joue aucun rôle dans la détermination de l'interpréteur approprié sous Linux.
(* Il est bien sûr possible de développer un algorithme "intelligent" de devin pour déterminer la syntaxe à partir du code.)
Vous pouvez y parvenir avec un script comme celui-ci:
#!/bin/bash
copy=/tmp/runner.$$
cp $1 ${copy}
chmod u+x ${copy}
${copy}
rm ${copy}
Ainsi:
$ echo "echo hello" > myscript
$ ./myscript
bash: ./myscript: Permission denied
$ ./runscript myscript
hello
Je recommande de ne pas faire cela. Les autorisations sont là pour une raison. Ceci est un programme pour subvertir les autorisations.
Notez que la gestion de Shebang est une fonction du noyau (dans le code source Linux - fs/binfmt_script.c
). Fondamentalement, le processus invoquant directement un script ne connaît pas le #!
- le noyau l'utilise pour déterminer qu'il lui faut lancer un interpréteur.