I’m currently studying penetration testing and Python programming. I just want to know how I would go about executing a Linux command in Python. The commands I want to execute are:
echo 1 > /proc/sys/net/ipv4/ip_forward iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 8080
If I just use print in Python and run it in the terminal will it do the same as executing it as if you was typing it yourself and pressing Enter?
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can use os.system(), like this:
import os
os.system('ls')
Or in your case:
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')
Better yet, you can use subprocess’s call, it is safer, more powerful and likely faster:
from subprocess import call
call('echo "I like potatos"', shell=True)
Or, without invoking shell:
call(['echo', 'I like potatos'])
If you want to capture the output, one way of doing it is like this:
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))
I highly recommend setting a timeout in communicate, and also to capture the exceptions you can get when calling it. This is a very error-prone code, so you should expect errors to happen and handle them accordingly.
https://docs.python.org/3/library/subprocess.html
Method 2
The first command simply writes to a file. You wouldn’t execute that as a shell command because python can read and write to files without the help of a shell:
with open('/proc/sys/net/ipv4/ip_forward', 'w') as f:
f.write("1")
The iptables command is something you may want to execute externally. The best way to do this is to use the subprocess module.
import subprocess
subprocess.check_call(['iptables', '-t', 'nat', '-A',
'PREROUTING', '-p', 'tcp',
'--destination-port', '80',
'-j', 'REDIRECT', '--to-port', '8080'])
Note that this method also does not use a shell, which is unnecessary overhead.
Method 3
The quickest way:
import os
os.system("your command here")
This isn’t the most flexible approach; if you need any more control over your process than “run it once, to completion, and block until it exits”, then you should use the subprocess module instead.
Method 4
As a general rule, you’d better use python bindings whenever possible (better Exception catching, among other advantages.)
For the echo command, it’s obviously better to use python to write in the file as suggested in @jordanm’s answer.
For the iptables command, maybe python-iptables (PyPi page, GitHub page with description and doc) would provide what you need (I didn’t check your specific command).
This would make you depend on an external lib, so you have to weight the benefits. Using subprocess works, but if you want to use the output, you’ll have to parse it yourself, and deal with output changes in future iptables versions.
Method 5
A python version of your shell. Be careful, I haven’t tested it.
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
Method 6
If you want to execute this command in some other system after SSH then you might have to use the module named Paramiko. It is really useful.
If the command execution has to be done from local machine then os module functions will be helpful.
Homepage: https://www.paramiko.org/
Development: https://github.com/paramiko/paramiko
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0