Execute shell commands in Python

  • 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?

    and i thought `bash` was a bloated shell...

    The docs for `os.system` recommend using the `subprocess` module.

    Do you need the output of iptables?

    Yeah I would like the output. You can execute commands in Python because I made a Dictionary Attacker from it and I have Python installed and I want to do this purely from Python just to quickly execute a command

    This question should be migrated to Stackoverflow.

  • Kira

    Kira Correct answer

    5 years ago

    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

    os.system is deprecated since version 2.6. Subprocess is the right module to use.

    @binarysubstrate, deprecated as in not supported or not available? I've been recently working on machine with 2.7 (not by choice), and `os.system` still works.

    Also, if using `subprocess.call` as recommended, you may need to specify `shell=True`... see here

    With Python 3.4 the shell=True has to be stated otherwise the call command will not work. By default call will try to open a file specified by the string unless the shell=True is set. It also looks like that in Python 3.5 call is replaced with run

    Generic POSIX code should probably call `decode()` with charset from `LC_CTYPE` environment variable.

License under CC-BY-SA with attribution


Content dated before 6/26/2020 9:53 AM