'comando sudo setsid' não gera novo grupo de processos?

1

Estou vendo um cenário em que quero executar um programa / comando com sudo como parte de um teste de software. Os comandos são iniciados a partir de um script Python baseado no módulo subprocess . Estou tentando evitar ter que executar o conjunto de testes inteiro com privilégios de superusuário.

Digamos que, para o propósito deste exemplo, é top . Meu comando inicia alguns subprocessos próprios e pode entrar em conflito. Depois de um tempo limite, eu quero matá-lo (e seus filhos). A solução óbvia parece ser tornar meu chefe de comando de um novo grupo de sessão / processo, permitindo que eu o mate e seus filhos de uma só vez. O que eu não consigo descobrir é como fazer isso funcionar com sudo . No meu caso, sudo é sempre protegido por senha, sem exceção e eu quero mantê-lo desta forma ... se possível.

  1. Trabalhos: setsid top
  2. Funciona, mas NÃO gera um novo grupo de processos: sudo setsid top
  3. Problemático - é difícil obter a senha de root de maneira segura e sadia: setsid sudo top

Eu não consegui fazer (3) funcionar de maneira limpa. Eu mexi com SUDO_ASKPASS .

O que me surpreendeu foi o fato de que (2) na verdade funciona, mas NÃO me fornece o novo grupo de processos desejado.

systemd─┬─ ...
        ├─kdeinit5─┬─ ...
        │          └─yakuake─┬─2*[bash]
        │                    ├─bash───sudo───top
        │                    ├─bash───pstree
        ...
    
por s-m-e 15.12.2017 / 12:34

1 resposta

1

O cenário 2 pode ser corrigido assim, sem o uso de setsid :

sudo -b command

Isso criará um novo grupo de processos, diretamente abaixo do processo de inicialização do sistema, incluindo o comando sudo .

Uma palavra de recomendação: se alguém inicia um grupo de processos como este com subprocess.Popen do Python, o PID ( subprocess.Popen(...).pid ) do objeto resultante NÃO pode ser usado para determinar o PGID para eventual uso em um padrão como kill -9 -- -{PGID} (ele eliminará o interpretador Python em vez do grupo de processos recém gerado). Minha solução alternativa (requer 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)))
    
por 15.12.2017 / 17:08