Como eu mato todos os processos de um usuário usando seu UID

41

Eu quero matar todos os processos em execução de um usuário específico a partir de um script de shell ou código nativo em um sistema Linux.

Preciso ler o diretório / proc e procurar por eles?

Alguma ideia? Existe um mapeamento dinâmico dos pids em UIDs no Linux? Isso não está no processo?

Caso contrário, onde essa lista é mantida? Devo ler sobre isso? Além disso, onde está a lista estática de todos os UIDs no sistema, para que eu possa validar essa existência desse usuário e continuar matando todos os processos em execução sob ele?

user489152
fonte
6
Você quer uma ferramenta para fazer isso (pkill, slay, outras existem), ou deseja escrever por conta própria? No primeiro caso, o site de troca de pilha de superusuário provavelmente é melhor. Nesse último caso, a digitalização / proc e a anotação de todos os processos por um usuário específico é o caminho a seguir. O código fonte do utilitário pkill mostraria, por exemplo, como fazer isso.
Você poderia esclarecer o que era essa pergunta à luz do comentário de @ LarsWirzenius? Obrigado!
Caleb
@ Caleb: Eu queria matar processos lendo o / proc, pois não sabia de nenhuma ferramenta. Agora também acho que outros que não sejam "kill", "pkill", "skill" etc. não estão disponíveis no meu sistema. Nesse caso, acho que preciso procurar alternativas de script de shell para ler o / proc e descobrir uma maneira de obter processos sob um usuário. Alguma ideia?
user489152
1
Em relação à “lista estática de todos os UIDs ... para que eu possa validar isso, este usuário existe”: não existe validação de um ID de usuário. Os nomes de usuário vêm de um banco de dados, mas os IDs de usuário são o que um processo em execução setuid()escolher.
Gilles 'SO- stop be evil'

Respostas:

53

Use pkill -U UIDou pkill -u UIDou nome de usuário em vez de UID. Às vezes skill -u USERNAMEpode funcionar, outra ferramenta é killall -u USERNAME.

O Skill era específico do Linux e agora está desatualizado, e o pkill é mais portátil (Linux, Solaris, BSD).

O pkill permite UIDs numéricos e simbólicos, efetivos e reais http://man7.org/linux/man-pages/man1/pkill.1.html

pkill - ... sinaliza processos com base no nome e outros atributos

    -u, --euid euid,...
         Only match processes whose effective user ID is listed.
         Either the numerical or symbolical value may be used.
    -U, --uid uid,...
         Only match processes whose real user ID is listed.  Either the
         numerical or symbolical value may be used.

A página de manual de habilidade diz que é permitido usar apenas o nome de usuário, não o ID do usuário: http://man7.org/linux/man-pages/man1/skill.1.html

habilidade, snice ... Essas ferramentas são obsoletas e não são portáveis. A sintaxe do comando está mal definida. Considere usar o killall, pkill

  -u, --user user
         The next expression is a username.

O killall não está marcado como desatualizado no Linux, mas também não funcionará com UID numérico; único nome de usuário: http://man7.org/linux/man-pages/man1/killall.1.html

killall - mata processos por nome

   -u, --user
         Kill only processes the specified user owns.  Command names
         are optional.

Eu acho que qualquer utilitário usado para encontrar processos no estilo Linux / Solaris / proc (procfs) usará a lista completa de processos (fazendo alguns readdir de /proc). Eu acho que eles irão percorrer /procsubpastas digitais e verificar todos os processos encontrados quanto à correspondência.

Para obter a lista de usuários, use getpwent(ele receberá um usuário por chamada).

As ferramentas skill (procps & procps-ng) e killall (psmisc) usam a getpwnamchamada de biblioteca para analisar o argumento da -uopção e apenas o nome de usuário será analisado. pkill(procps & procps-ng) usa atol e getpwnam para analisar -u/ -Uargumentar e permitir o especificador de usuário numérico e textual.

osgx
fonte
1
pkill não é obsoleto. Pode ser portável fora do Linux, mas a pergunta era sobre o Linux especificamente.
1
para obter a lista de usuários, use o liner único: getent passwd | awk -F: '{print $ 1}'
Petesh
e se eu der um comando como: "kill -ju UID" da chamada do sistema C ()?
1
é um linux embutido? você não tem habilidade, pkill e killall? Mesmo o shell incorporado do busybox tem pkill e killall.
Osgx
2
killall -u USERNAMEfuncionou como encanto
michalzuber
8

Se você passar -1 como argumento do ID do processo para o killcomando shell ou para a killfunção C , o sinal será enviado para todos os processos que ele puder alcançar, o que, na prática, significa todos os processos do usuário executando o killcomando ou syscall.

su -c 'kill -TERM -1' bob

Em C (verificação de erro omitida):

if (fork() == 0) {
    setuid(uid);
    signal(SIGTERM, SIG_DFL);
    kill(-1, SIGTERM);
}
Gilles 'SO- parar de ser mau'
fonte
5

Se a função pkill não estiver disponível na sua distribuição UNIX / Linux, você poderá executar o seguinte comando como usuário root:

ps -ef | grep username | grep -v grep | awk '{print $2}' | xargs kill

onde username é o usuário que processa você deseja excluir

Comunidade
fonte
ou apenas o pkill -U username.
Osgx
2
pgrep -U username|xargs kill -9
Alexander
fonte
0

Isso funcionou muito bem para mim. Você pode encontrar todos os detalhes dos processos por nome de usuário, fazendo ps U <username>e indo a partir daí. Tente o seguinte:

ps U <username> | cut -d " " -f 1 | xargs kill
jasonrhaas
fonte