1

I am looking at a scenario where I want to run a program / command with sudo as part of a software test. The commands are launched from a Python script based on the subprocess module. I am attempting to avoid having to run the entire test suite with super user privileges.

Let's say for the purpose of this example, it's top. My command starts a few sub-processes of its own and may run into a deadlock. After a timeout, I want to kill it (and its children). The obvious solution appears to be to make my command head of a new session / process group, allowing me to kill it and its children altogether at once. What I can NOT figure out is how to make this work with sudo. In my case, sudo is always password protected without exception and I want keep it this way ... if possible.

  1. Works: setsid top
  2. Works, but does NOT spawn a new process group: sudo setsid top
  3. Problematic - hard to get the root password in in a safe and sound manner: setsid sudo top

I did not manage to make (3) work in a clean way. I messed around with SUDO_ASKPASS.

What surprised me was the fact that (2) actually runs but does NOT give me the desired new process group.

systemd─┬─ ...
        ├─kdeinit5─┬─ ...
        │          └─yakuake─┬─2*[bash]
        │                    ├─bash───sudo───top
        │                    ├─bash───pstree
        ...
7
  • Ar you looking for subprocess.CREATE_NEW_PROCESS_GROUP?
    – muru
    Dec 15, 2017 at 11:49
  • @muru My Python process runs with normal user privileges. I know its perfectly possible to make Popen launch a process into a new group - there are in fact multiple ways of doing that. But all of those run into issues associated with scenario 3, i.e. SUDO_ASKPASS, when I try to run something like subprocess.Popen(['sudo', 'top'], start_new_session = True). I was hoping to figure out a way of starting a new session AFTER sudo asks for the password.
    – s-m-e
    Dec 15, 2017 at 11:57
  • 1
    @s-m-e sudo -b might help (askubuntu.com/a/750423/158442)
    – muru
    Dec 15, 2017 at 11:58
  • @muru Yep, sudo -b top works, it appears to fire up a new process group. No setsid required. Thanks :)
    – s-m-e
    Dec 15, 2017 at 12:10
  • @muru subprocess.CREATE_NEW_PROCESS_GROUP is Windows only ...
    – s-m-e
    Dec 15, 2017 at 16:09

1 Answer 1

1

Scenario 2 can be fixed like this, without the use of setsid:

sudo -b command

This will create a new process group, directly below the system's init process, including the sudo command.


One word of advise, though: If one starts a process group like this with Python's subprocess.Popen, the resulting object's PID (subprocess.Popen(...).pid) can NOT be used for determining the PGID for eventual use in a pattern like kill -9 -- -{PGID} (it will kill the Python interpreter instead of the newly spawned process group). My workaround (requires psutil):

import os
import psutil
import subprocess

def __get_pid__(cmd_line_list):
    for pid in psutil.pids():
        proc = psutil.Process(pid)
        if cmd_line_list == proc.cmdline():
            return proc.pid
    return None

cmd = ['sudo', '-b', 'command']
cmd_proc = subprocess.Popen(cmd)

print('Wrong PGID: %d' % os.getpgid(cmd_proc.pid))
print('Right PGID: %d' % os.getpgid(__get_pid__(cmd)))

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .