Skip to content

Instantly share code, notes, and snippets.

@aeroaks
Last active September 10, 2023 15:28
Show Gist options
  • Save aeroaks/f6150bd0add14bdbc244 to your computer and use it in GitHub Desktop.
Save aeroaks/f6150bd0add14bdbc244 to your computer and use it in GitHub Desktop.
Run Sudo command using Python
import subprocess
# run command using Popen and provide password using communicate.
# password requires byte format.
# sudo -S brings password request to PIPE
proc = subprocess.Popen(['sudo', '-S', 'nano', 'test.txt'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate(input=b'password\n')
# Print output and errors
print(proc)
@Teddykavooh
Copy link

The above code throws the following error:
b'Standard input is not a terminal\n'
But it works well with other commands. Why's that?

@cloudgnome
Copy link

because "nano" program uses terminal for output?

@Teddykavooh
Copy link

I'll try to add shell=true and see if it works but I'm not really confident about it since I've already defined the shebang. Thanks for the reply.

@cloudgnome
Copy link

if you run it like python sudo_test.py from command line you will have result. because its complete output of interpreted code read line by line. it doesnt loop in main like C code and does not await for your password.

Sorry, try again.
('', 'Password:Password:\nsudo: no password was provided\nsudo: 1 incorrect password attempt\n')

if you do just nano test.txt and check system processes, you can see your nano as process that works in loop and awaits for your input and makes output:

ps aux | grep nano
dd                 795   0.0  0.0  4258468    196 s002  U+    4:47PM   0:00.00 grep nano
dd                 792   0.0  0.0  4277208   1796 s003  S+    4:47PM   0:00.01 nano test.txt

@Rajan-sust
Copy link

Rajan-sust commented Sep 10, 2023

from subprocess import Popen, PIPE, STDOUT

password = 'xxxxxx'
cmd = f'echo {password} | sudo -S nano test.txt'

with Popen(cmd, shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE, text=True) as process:
    # Wait for the command to complete and collect its output
    stdout, stderr = process.communicate()
    # Optionally, you can check the exit code and print the output
    if process.returncode == 0:
        print('Command succeeded:')
        print(stdout)
    else:
        print('Command failed:')
        print(stderr)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment