Actualmente estoy estudiando pruebas de penetración y programación en Python. Solo quiero saber cómo haría para ejecutar un comando de Linux en Python. Los comandos que quiero ejecutar son:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
Si solo uso print
en Python y ejecútelo en la terminal, ¿hará lo mismo que ejecutarlo como si lo estuviera escribiendo usted mismo y presionando Enter ?
Comentarios
Respuesta
Puede usar os.system()
, así:
import os os.system("ls")
O en su caso:
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")
Mejor aún, puede usar la llamada del subproceso, es más seguro, más potente y probablemente más rápido:
from subprocess import call call("echo "I like potatos"", shell=True)
O, sin invocar el shell:
call(["echo", "I like potatos"])
Si desea capturar el resultado, una forma de hacerlo es así:
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))
Recomiendo encarecidamente configurar un timeout
en communicate
, y también para capturar las excepciones que puede obtener al llamarlo. Este es un código muy propenso a errores, por lo que debe esperar que ocurran errores y manejarlos en consecuencia.
https://docs.python.org/3/library/subprocess.html
Comentarios
- os.system está obsoleto desde la versión 2.6. El subproceso es el módulo correcto para usar.
- @binarysubstrate, en desuso porque no es compatible o no está disponible? ‘ estuve trabajando recientemente en una máquina con 2.7 (no por elección), y
os.system
todavía funciona. - Además, si usa
subprocess.call
como se recomienda, es posible que deba especificarshell=True
… consulte aquí - Con Python 3.4, se debe establecer shell = True, de lo contrario, el comando de llamada no funcionará. Por defecto, la llamada intentará abrir un archivo especificado por la cadena a menos que se establezca shell = True. También parece que en Python 3.5 la llamada se reemplaza por ejecutar
- El código POSIX genérico probablemente debería llamar a
decode()
con el juego de caracteres deLC_CTYPE
variable de entorno.
Respuesta
El primer comando simplemente escribe en un archivo. No lo ejecutaría como un comando de shell porque python
puede leer y escribir archivos sin la ayuda de un shell:
with open("/proc/sys/net/ipv4/ip_forward", "w") as f: f.write("1")
El comando iptables
es algo que quizás desee ejecutar externamente. La mejor manera de hacerlo es usar el módulo de subproceso .
import subprocess subprocess.check_call(["iptables", "-t", "nat", "-A", "PREROUTING", "-p", "tcp", "--destination-port", "80", "-j", "REDIRECT", "--to-port", "8080"])
Tenga en cuenta que este método tampoco utiliza un shell, que es una sobrecarga innecesaria.
Respuesta
La forma más rápida:
import os os.system("your command here")
Este no es el enfoque más flexible ; si necesita más control sobre su proceso que «ejecutarlo una vez, hasta completarlo y bloquearlo hasta que salga», entonces debe usar el módulo subprocess
en su lugar.
Respuesta
Como regla general, es mejor que use enlaces de Python siempre que sea posible (mejor captura de excepciones, entre otras ventajas).
Para el comando echo
, obviamente es mejor usar Python para escribir en el archivo como se sugiere en la respuesta de @jordanm.
Para el iptables
comando, tal vez python-iptables
( página PyPi , La página de GitHub con la descripción y el documento ) proporcionaría lo que necesita (no verifiqué su comando específico).
Esto lo haría depender de un lib externa, por lo que debe sopesar los beneficios. El uso de subprocesos funciona, pero si desea utilizar la salida, tendrá que analizarla usted mismo y ocuparse de los cambios de salida en versiones futuras iptables
.
Comentarios
- Otra cosa a tener en cuenta es que el código de prueba unitaria con llamadas
subprocess
es menos útil. Sí, puedes simular el llamadas, pero las pruebas tienen que hacer suposiciones sobre los resultados de las llamadas externas. - Su respuesta es más como un consejo. El OP ha preguntado específicamente cómo puede ejecutar un comando del sistema Linux desde python.
- @kapad Sí, pero también especificó por qué quería hacerlo y le propuse una alternativa.
Respuesta
Una versión en Python de su shell. Tenga cuidado, no la he probado.
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
Comentarios
- La división de cadenas solo funciona para los casos simples. Para la división de comandos de estilo shell, use
shlex.split
Respuesta
Si desea ejecutar este comando en algún otro sistema después de SSH, es posible que deba usar el módulo llamado Paramiko. Es realmente útil.
Si la ejecución del comando debe realizarse desde la máquina local, las funciones del módulo del sistema operativo serán útiles.
Página de inicio: https://www.paramiko.org/
Desarrollo: https://github.com/paramiko/paramiko
bash
era un caparazón hinchado …os.system
recomiendan usar elsubprocess
módulo.