Como posso pedir ps
para exibir apenas processos do usuário e não threads do kernel?
Veja esta pergunta para ver o que quero dizer ...
Como posso pedir ps
para exibir apenas processos do usuário e não threads do kernel?
Veja esta pergunta para ver o que quero dizer ...
Respostas:
Isso deve fazer (no Linux):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) possui PPID 0 ( no Linux 2.6+ ), mas ps
não permite filtrar o PPID 0; assim, esta solução alternativa.
kthreadd
e crie a ps
chamada de acordo . Qual é a garantia de que essa coisa "sempre" será chamada de "kthreadd"? Uma solução segura seria mais complicada, execute ps
normalmente e analise a saída, talvez faça alguns testes.
x
bandeira que não funciona com isso. ps au --ppid 2 -p 2 --deselect
funciona bem.
Uma maneira de reconhecer os processos do kernel é que eles não usam nenhuma memória do usuário, então o campo vsz é 0. Isso também captura zumbis (graças a Stephane Chazelas por essa observação), que podem ser eliminados com base em seu status.
ps axl | awk '$7 != 0 && $10 !~ "Z"'
Para listar apenas os PIDs:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
Na prática, encontrei o seguinte idioma o suficiente:
ps auxf | grep -v ]$
Ele filtra as linhas que terminam com colchetes, o que pode resultar na omissão de entradas indesejadas, mas é muito improvável. Em troca, é bastante fácil de lembrar e relativamente rápido de digitar.
Alguns processos como o avahi-daemon adicionam informações de nome de processo entre colchetes (o nome do host no caso do avahi-daemon) e serão filtrados por este comando.
Uma das particularidades desses processos é que eles não são apoiados por um arquivo executável; portanto, você pode fazer ( no zsh ):
ps /proc/[0-9]*/exe(^-@:h:t)
Ou com qualquer shell POSIX:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
Essa é a verificação de processos cujo /proc/<pid>/exe
link para um arquivo.
Mas isso significa que você precisa ser superusuário para poder verificar o estado do /proc/<pid>/exe
link simbólico.
Editar : como acontece com os processos zumbis (pelo menos), eles satisfazem a mesma condição; portanto, se você não os quiser excluídos, será necessário adicioná-los novamente. Gostar:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
Observe que ps -f
mostra esses nomes de processos entre colchetes não porque são processos do kernel, mas porque eles estão vazios argv[]
(então o ps mostra o nome do processo em vez de argv[0]
lá). Você pode ter um processo de espaço do usuário com um vazio argv[]
também e pode ter um nome de processo com argv[0]
esse formato, [some-string]
portanto, filtrar a ps
saída com base nesses colchetes não é uma opção infalível.
zsh
sintaxe. O segundo é a sintaxe padrão POSIX sh
(e ps
and find
and cut
and paste
). Claro que /proc
não é especificado pelo POSIX.
wc -l
). Bem, eu aceitarei a resposta de Hauke Laging e darei-lhe um voto positivo . ;)
Você também pode apenas analisar a ps
saída e procurar nomes de processos que não estão entre colchetes:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
- mas você ainda terá processos que mencionam esse nome de usuário e deixará o arquivo temporário por aí. Retirei meu voto negativo, mas apenas porque sua terceira solução é razoável.
$NF
é a última palavra da linha de comando na ps aux
saída. Processos que não são do kernel podem ter [...]
lá. Como eu disse na minha resposta, a [xxx]
notação não é porque eles são processos do kernel, mas porque eles não têm linha de comando (nenhum argumento), o que também é permitido para processos que não são do kernel.
Para quem tenta fazer isso no busybox, onde ps
é bastante simplificado e a saída é diferente, essa variante da grande resposta de Gilles funciona bem:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
De acordo com a resposta de Gilles, a metodologia aqui é encontrar processos que não usem memória do usuário (`vsz col == 0) e filtrar os processos zumbis (status col não é 'Z').
As colunas de saída podem ser ajustadas facilmente, desde que os números dos campos awk com base em 1 sejam ajustados de acordo. Veja as opções que seu ps tem disponível, colocando um valor falso e ele informará. Por exemplo:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Se você precisar apenas das contagens ... Eu tinha uma necessidade semelhante de filtrar o kernel versus os processos do usuário, mas eu precisava apenas das respectivas contagens de cada um. Esta foi a minha solução:
ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'
Saída de amostra :
Kernel processes 353
User processes 52
Total processes 405
Explicação : Estou usando o hack que processos VSZ = 0 podem ser considerados processos do kernel. Portanto awk
, avalio uma comparação no VSZ (de ps -eo vsize
), se é igual a zero. O resultado da comparação será um 0 ou 1. booleano. Eu faço uma matriz p[]
e, ao percorrer a lista de processos, se for um processo do kernel, incremento p[1]++
. Caso contrário, como processo do usuário, eu incremento p[0]++
. Após todo o incremento, rotulo e imprimo os valores (ou seja, contagens) para p [0] ep [1] no END { }
bloco.
O que você está procurando, meu amigo, não é ps
, mas pstree
.
Primeiro, identifique o primeiro processo do kernel. Seu PID é geralmente 1 no sistema sem systemd e 2 com systemd.
Então use este comando:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
A resposta selecionada (uma com ✅) está usando outro comando:
$ ps --ppid 2 -p 2 --deselect
O problema com este ps
comando é que ele inclui apenas filhos diretos, mas nem todos os descendentes. O pstree
comando inclui todos os descendentes. Você pode comparar e contar a saída desses dois comandos (é uma maneira fácil de usar | wc
) para verificar.
kthreadd
é sempre o PID 2?