dredbound
dredbound

Reputation: 1659

Python subprocess sudo returns error: ERROR: ['sudo: sorry, you must have a tty to run sudo\n']

Here is my code:

import subprocess

HOST = 'host_name'
PORT = '111'
USER = 'user_name'
CMD = 'sudo su - ec2-user; ls'

process = subprocess.Popen(['ssh','{}@{}'.format(USER, HOST),
                        '-p', PORT, CMD],
                       shell=False,
                       stdout=subprocess.PIPE,
                       stderr=subprocess.PIPE)

result = process.stdout.readlines()

if not result:
    print "Im an error"
    err = process.stderr.readlines()
    print('ERROR: {}'.format(err))
else:
    print "I'm a success"
    print(result)

When I run this I receive the following output in my terminal:

dredbounds-computer: documents$ python terminal_test.py
Im an error
ERROR: ['sudo: sorry, you must have a tty to run sudo\n']

I've tried multiple things but I keep getting that error "sudo: sorry, you must have a tty to run sudo". It works fine if I just do it through the terminal manually, but I need to automate this. I read that a workaround might be to use '-t' or '-tt' in my ssh call, but I haven't been able to implement this successfully in subprocess yet (terminal just hangs for me). Anyone know how I can fix my code, or work around this issue? Ideally I'd like to ssh, then switch to the sudo user, and then run a file from there (I just put ls for testing purposes).

Upvotes: 1

Views: 4393

Answers (2)

miken32
miken32

Reputation: 42695

You can tell sudo to work without requiring a password. Just add this to /etc/sudoers on the remote server host_name.

user ALL = (ec2-user) NOPASSWD: ls

This allows the user named user to execute the command ls as ec2-user without entering a password.

This assumes you change your command to look like this, which seems more reasonable to me:

CMD = 'sudo -u ec2-user ls'

Upvotes: 0

chepner
chepner

Reputation: 531055

sudo is prompting you for a password, but it needs a terminal to do that. Passing -t or -tt provides a terminal for the remote command to run in, but now it is waiting for you to enter a password.

process = subprocess.Popen(['ssh','-tt', '{}@{}'.format(USER, HOST),
                          '-p', PORT, CMD],
                          shell=False,
                          stdout=subprocess.PIPE,
                          stderr=subprocess.PIPE,
                          stdin=subprocess.PIPE)
process.stdin.write("password\r\n")

Keep in mind, though, that the ls doesn't run until after the shell started by su exits. You should either log into the machine as ec2-user directly (if possible), or just use sudo to run whatever command you want without going through su first.

Upvotes: 2

Related Questions