Команда su
ожидает чтения из терминала. Выполнение приведенного выше примера на моей машине с Linux возвращает следующую ошибку:
su: must be run from a terminal
Это потому, что su
пытается убедиться, что он запускается из терминала. Вы можете обойти это, выделив pty и управляя вводом и выводом самостоятельно, но получить это право может быть довольно сложно, потому что вы не можете ввести пароль до тех пор, пока su не запросит его. Например:
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)
Существует библиотека под названием pexpect , которая делает взаимодействие с интерактивными приложениями довольно простым:
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("#")