11

I am trying to execute sudo commands from Python 3. I usually run my terminal commands in Python using subprocess. There are already many questions discussing this topic but I could not find any solution that works for me.

My Os is Ubuntu 18.04 and I am working with Python 3.6 and PyCharm.

I cannot manage to enter the password using subprocess no matter how I try. My script always gets stuck trying to enter the sudo password. After the first answer I realized, that the problem is not about my Code, the Problem is with PyCharm. All the following attempts work fine when running them from Console, but they get stuck when I am running them from the PyCharm Interpreter. Here are all the versions I tried:

Attempt 1:

import subprocess
sudo_password = b"myPassword\n"

print(subprocess.check_output('sudo -S echo success', shell=True, input=sudo_password)) #stuck here

This seemed to be the easiest way of solving the issue, but somehow subprocess could not enter the password, it would always get stuck until I killed the process.

Attempt 2:

import subprocess
sudo_password = b"myPassword\n"

proc = subprocess.Popen('sudo -S echo success', shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
proc.stdin.write(sudo_password)
proc.stdin.flush()
print(proc.stdout.readlines()) #stuck here

On my second attempt I tried to handle the instream myself which did not seem to work either. The program would get stuck when reading the lines of the outstream. When I abort the code I get following Error message indicating that the console has been prompted for the password but It could somehow not be entered.

Traceback (most recent call last):
  File "/home/anon/sudo.py", line 7, in <module>
[sudo] password for anon:     print(proc.stdout.readlines()) #stuck here
KeyboardInterrupt

Attempt 3:

I knew that I could pipe the password into the sudo command from terminal:

anon@anon:~$ echo myPassword | sudo -S echo success
[sudo] password for anon: success

So I tried to do the same thing using subprocess:

import subprocess
sudo_password = "myPassword"

print(subprocess.check_output("echo {} | sudo -S echo success".format(sudo_password), shell=True)) #stuck here

But yet again this approach just got stuck just like all the other approaches.

Attempt 4:

import subprocess
import os
sudo_password = "myPassword"

with open("temp.sh", 'w') as file:
    file.write("echo {} | sudo -S echo success".format(sudo_password))

print(subprocess.check_output("sh temp.sh", shell=True)) #stuck here

os.remove("temp.sh")

So in my last desperate attempt I thought I might succeed if I put my command into a shell file and execute that with subprocess since I would not have any sudo commands entered directly to subprocess. This worked out well when I tried it in the terminal myself:

anon@anon:~$ sh temp.sh 
[sudo] password for anon: success

But the Python script got stuck at the same place as before.

Does anyone know why these attempts fail and how I could achieve my goal anyways?

Edit:

Someone linked me an old post about this topic which used os instead of subprocess. os is deprecated and subprocess should be used instead thats why I haven't originally shown any of these attempts in this question, but it does also get stuck when using os:

import os
sudo_password = "myPassword"

p = os.system('echo {} | sudo -S echo success'.format(sudo_password)) #stuck here

Edit 2:

Ok now I figured out, that all of my attempts and also the suggestion from the first answer would actually work if you run the scripts from terminal with:

anon@anon:~$ python3 checksudo.py

So the problem seem to lay with my interpreter, PyCharm. This is also what makes my question unique to this question, because their issue does not come from their interpreter.

Does anyone have any suggestions how to make the code work in PyCharm or should I just run all my scripts from Console anyways?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Yannick
  • 337
  • 3
  • 13
  • 1
    https://stackoverflow.com/questions/13045593/using-sudo-with-python-script – Lasith Niroshan Jul 07 '18 at 16:05
  • Looks like `.format(sudo_password)` is missing in the 3rd attempt. – ducminh Jul 07 '18 at 16:43
  • Possible duplicate of [Using sudo with Python script](https://stackoverflow.com/questions/13045593/using-sudo-with-python-script) –  Jul 07 '18 at 17:45
  • This is a duplicate because the older question is called "Using sudo with Python script", which is exactly what you are asking. Also, many of the answers there also include using subprocesses, not os, which was why you stated that you dismissed the old question. –  Jul 07 '18 at 17:47
  • Did you consider fixing the `/etc/sudoers` file with `visudo` to suppress the password prompt? Also, have you looked into `pexpect` instead of subprocess since pexpect is meant to deal with interactive CLI (https://stackoverflow.com/questions/39907546/how-to-perform-a-root-command-with-pexpect)? – tk421 Jul 08 '18 at 03:26

1 Answers1

2

How about:

# coding=utf-8

from subprocess import Popen, PIPE

sudo_password = 'mypass'
command = 'echo success'.split()

p = Popen(['sudo', '-S'] + command, stdin=PIPE, stderr=PIPE,
          universal_newlines=True)
sudo_prompt = p.communicate(sudo_password + '\n')[1]
print('Done!')

Of course, make sure you put in the correct password to your code.

  • Still does not work. It gets stuck on the last line, even after entering the correct password. When i add **print(sudo_promt)** at the end it never gets reached. – Yannick Jul 07 '18 at 16:59
  • I ran this exact cut-and-paste code (changing the password only) and got the desired "success" output. –  Jul 07 '18 at 17:07
  • why are you printing? Read the code; you must use `communicate` –  Jul 07 '18 at 17:08
  • I added a `print('Done!')` that shows the python code is not stopped by the communication. Even if the password is wrong, only the actual command (echo success) will not work. –  Jul 07 '18 at 17:42
  • Thank you, you suggestion as well as all of my attempts would have actually worked if you run them from console. My issue seems to be my interpreter, PyCharm. – Yannick Jul 09 '18 at 08:26
  • interesting, because I ran this in pycharm –  Jul 12 '18 at 11:48
  • do you run PyCharm as root? – Yannick Jul 12 '18 at 13:32
  • not as far as I know... I installed per the instructions. –  Jul 12 '18 at 19:29
  • I have Mint, which really does not have a root account. –  Jul 12 '18 at 19:30