Exécutez des commandes shell en

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

  • os.system peuvent le faire.
  • et jai pensé bash était un shell gonflé …
  • La documentation pour os.system recommande dutiliser le subprocess module.
  • Avez-vous besoin de la sortie diptables?
  • Cette question doit être migrée vers Stackoverflow.

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écifier shell=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 de LC_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

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *