J'étudie actuellement les [tests de pénétration][1] et la programmation Python. Je veux juste savoir comment je pourrais 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 j'utilise simplement print
en Python et que je l'exécute dans le terminal, est-ce qu'elle sera exécutée de la même manière que si vous la tapiez vous-même et que vous appuyiez sur Enter ?
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 l'appel du sous-processus, c'est plus sûr, plus puissant et probablement plus rapide :
from subprocess import call
call('echo "I like potatos"', shell=True)
Ou, sans invoquer le shell :
call(['echo', 'I like potatos'])
Si vous voulez capturer la sortie, une façon de le faire est la suivante :
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 recommande hautement de mettre un timeout
dans communicate
, et aussi de capturer les exceptions que vous pouvez obtenir en l'appelant. C'est un code très sujet aux erreurs, donc vous devez vous attendre à ce que des erreurs se produisent et les gérer en conséquence.
La première commande écrit simplement dans un fichier. Vous ne l'exécuteriez pas en tant que commande shell, car python
peut lire et écrire dans des fichiers sans l'aide d'un shell :
with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
f.write("1")
La commande iptables
est quelque chose que vous pouvez vouloir exécuter en externe. La meilleure façon de le faire est d'utiliser le module subprocess.
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 n'utilise pas non plus de shell, ce qui représente une surcharge inutile.
Le moyen le plus rapide :
import os
os.system("your command here")
Ce n'est pas l'approche la plus flexible ; si vous avez besoin de plus de contrôle sur votre processus que "l'exécuter une fois, jusqu'à la fin, et bloquer jusqu'à ce qu'il sorte" ;, alors vous devriez utiliser le module subprocess
à la place.