Jétudie actuellement les tests de pénétration et la programmation Python. Je veux juste savoir comment je procéderais pour exécuter une commande Linux en Python. Les commandes que je veux exécuter sont:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Si jutilise simplement print
en Python et lexécuter dans le terminal fera-t-il la même chose que de lexécuter comme si vous le tapiez vous-même et appuyez sur Entrée ?
Les commentaires
Réponse
Vous pouvez utiliser os.system()
, comme ceci:
import os os.system("ls")
Ou dans votre cas:
os.system("echo 1 > /proc/sys/net/ipv4/ip_forward") os.system("iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080")
Mieux encore, vous pouvez utiliser lappel de sous-processus, cest plus sûr, plus puissant et probablement plus rapide:
from subprocess import call call("echo "I like potatos"", shell=True)
Ou, sans appeler le shell:
call(["echo", "I like potatos"])
Si vous voulez capturer la sortie, une façon de le faire est comme ceci:
import subprocess cmd = ["echo", "I like potatos"] proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) o, e = proc.communicate() print("Output: " + o.decode("ascii")) print("Error: " + e.decode("ascii")) print("code: " + str(proc.returncode))
Je fortement recommande de définir un timeout
dans communicate
, et aussi pour capturer les exceptions que vous pouvez obtenir en lappelant. Il sagit dun code très sujet aux erreurs, vous devez donc vous attendre à ce que des erreurs se produisent et les gérer en conséquence.
https://docs.python.org/3/library/subprocess.html
Commentaires
- os.system est obsolète depuis la version 2.6. Le sous-processus est le bon module à utiliser.
- @binarysubstrate, obsolète car non pris en charge ou non disponible? Jai ‘ récemment travaillé sur une machine avec 2.7 (pas par choix), et
os.system
fonctionne toujours. - De plus, si vous utilisez
subprocess.call
comme recommandé, vous devrez peut-être spécifiershell=True
… voir ici - Avec Python 3.4, le shell = True doit être indiqué sinon la commande call ne fonctionnera pas. Par défaut, lappel essaiera douvrir un fichier spécifié par la chaîne à moins que le shell = True soit défini. Il semble également que dans Python 3.5, lappel est remplacé par run
- Le code POSIX générique devrait probablement appeler
decode()
avec le jeu de caractères deLC_CTYPE
variable denvironnement.
Réponse
La première commande écrit simplement dans un fichier. Vous ne lexécuteriez pas en tant que commande shell car python
peut lire et écrire dans des fichiers sans laide dun shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
La commande iptables
est quelque chose que vous voudrez peut-être exécuter en externe. La meilleure façon de faire est dutiliser la module de sous-processus .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Notez que cette méthode nutilise pas non plus de shell, ce qui est inutile.
Réponse
Le moyen le plus rapide:
import os os.system("your command here")
Cette approche nest pas la plus flexible ; si vous avez besoin de plus de contrôle sur votre processus que « lexécuter une fois, jusquà la fin et le bloquer jusquà ce quil se termine », alors vous devriez utiliser le module subprocess
à la place.
Réponse
En règle générale, vous feriez mieux dutiliser les liaisons python chaque fois que possible (meilleure détection des exceptions, entre autres avantages).
Pour la commande echo
, il est évidemment préférable dutiliser python pour écrire dans le fichier comme suggéré dans la réponse de @jordanm.
Pour le iptables
commande, peut-être python-iptables
( page PyPi , La page GitHub avec description et doc ) fournirait ce dont vous avez besoin (je nai pas vérifié votre commande spécifique).
Cela vous ferait dépendre dun lib externe, vous devez donc peser les avantages. Lutilisation de sous-processus fonctionne, mais si vous souhaitez utiliser la sortie, vous « devrez lanalyser vous-même et gérer les modifications de sortie dans les futures versions de iptables
.
Commentaires
- Une autre chose à noter est que le code de test unitaire avec des appels
subprocess
est moins utile. Oui, vous pouvez simuler le appels, mais les tests doivent faire des hypothèses sur les résultats des appels externes. - Votre réponse ressemble plus à un conseil. LOP a spécifiquement demandé comment il pouvait exécuter une commande système Linux à partir de python.
- @kapad Oui, mais il a également précisé pourquoi il voulait le faire et jai proposé une alternative.
Réponse
Une version python de votre shell. Attention, je ne lai pas testé.
from subprocess import run def bash(command): run(command.split()) >>> bash("find / -name null") /dev/null /sys/fs/selinux/null /sys/devices/virtual/mem/null /sys/class/mem/null /usr/lib/kbd/consoletrans/null
Commentaires
- Le fractionnement de chaînes ne fonctionne que pour les cas simples. Pour le fractionnement des commandes de type shell, utilisez
shlex.split
Answer
Si vous souhaitez exécuter cette commande dans un autre système après SSH, vous devrez peut-être utiliser le module nommé Paramiko. Cest vraiment utile.
Si lexécution de la commande doit être effectuée à partir dune machine locale, les fonctions du module os seront utiles.
Page daccueil: https://www.paramiko.org/
Développement: https://github.com/paramiko/paramiko
bash
était un shell gonflé …os.system
recommande dutiliser lesubprocess
module.