I am trying to make a simple Python script that enters a given password in the command line after using the 'su' command (or any other command which requires administrator privileges or simply requires a password in order to be executed).
I tried to use the Subprocess module for this as well as pynput, but haven't been able to figure it out.
import subprocess
import os
# os.system('su') # Tried using this too
process = subprocess.Popen('su', stdin=subprocess.PIPE, stdout=subprocess.PIPE)
process.stdin.write(b"password_to_enter")
print(process.communicate()[0])
process.stdin.close()
I was expecting this to enter 'password_to_enter' in the given password prompt after typing the 'su' command, but it didn't. I tried giving it the correct password as well but still did not work.
What am I doing wrong?
PS: I am on Mac
The su
command expects to be reading from a terminal. Running your example above on my Linux machine returns the following error:
su: must be run from a terminal
This is because su
tries to make sure it's being run from a terminal. You can bypass this by allocating a pty and managing input and output yourself, but getting this right can be pretty tricky because you can't enter the password until after su prompts for it. For example:
import subprocess
import os
import pty
import time
# Allocate the pty to talk to su with.
master, slave = pty.openpty()
# Open the process, pass in the slave pty as stdin.
process = subprocess.Popen('su', stdin=slave, stdout=subprocess.PIPE, shell=True)
# Make sure we wait for the "Password:" prompt.
# The correct way to do this is to read from stdout and wait until the message is printed.
time.sleep(2)
# Open a write handle to the master end of the pty to write to.
pin = os.fdopen(master, "w")
pin.write("password_to_enter\n")
pin.flush()
# Clean up
print(process.communicate()[0])
pin.close()
os.close(slave)
There's a library called pexpect that makes interacting with interactive applications pretty simple:
import pexpect
import sys
child = pexpect.spawn("su")
child.logfile_read = sys.stdout
child.expect("Password:")
child.sendline("your-password-here")
child.expect("#")
child.sendline("whoami")
child.expect("#")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With