O ps pode exibir apenas processos que não são do kernel no Linux?

Respostas:

37

Isso deve fazer (no Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) possui PPID 0 ( no Linux 2.6+ ), mas psnão permite filtrar o PPID 0; assim, esta solução alternativa.

Hauke ​​Laging
fonte
Bom, mas como é garantido que kthreaddé sempre o PID 2?
l0b0
@ l0b0 Não faço idéia :-) Você pode fazer isso em duas etapas: determine o PID de kthreadde crie a pschamada de acordo . Qual é a garantia de que essa coisa "sempre" será chamada de "kthreadd"? Uma solução segura seria mais complicada, execute psnormalmente e analise a saída, talvez faça alguns testes.
amigos estão dizendo sobre hauke laging
2
No Linux 2.4 no arco x86, pelo menos, esses processos tinham o ppid 1 e, portanto, não podiam ser distinguidos dessa maneira.
Stéphane Chazelas
11
ser como "ps -ef" do "ps --ppid 2 -p 2 --deselecione -f" e fazê-lo como "ps aux" do "ps --ppid 2 -p 2 --deselecione u"
Peter
11
@ Motor verifiquei e parece que é a xbandeira que não funciona com isso. ps au --ppid 2 -p 2 --deselectfunciona bem.
Sankalp
9

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}'
Gilles 'SO- parar de ser mau'
fonte
Como minha solução, também incluirá processos zumbis.
Stéphane Chazelas
11
@StephaneChazelas Bom ponto, adicionei uma condição ao filtro.
Gilles 'SO- stop be evil'
9

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.

onetom
fonte
8

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>/exelink para um arquivo.

Mas isso significa que você precisa ser superusuário para poder verificar o estado do /proc/<pid>/exelink 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 -fmostra 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 pssaída com base nesses colchetes não é uma opção infalível.

Stéphane Chazelas
fonte
Esta é uma sintaxe não padrão do shell, eu acho.
Totor
11
@ Motor, como eu disse, o primeiro é zshsintaxe. O segundo é a sintaxe padrão POSIX sh(e psand findand cutand paste). Claro que /procnão é especificado pelo POSIX.
Stéphane Chazelas
Aceitando esta resposta porque é universal (obrigado pela edição). No entanto, a resposta de Hauke ​​Laging também é bastante agradável e direta, desde que você não lide com um kernel 2.4.
Totor
@Totor, a resposta de Hauke ​​também tem a vantagem de não exigir privilégios de superusuário. Minha resposta funciona com os kernels 2.4 e 2.6 / 3, mas suponho que não há garantia de que funcione no 4.x de qualquer maneira.
Stéphane Chazelas
Hmm, você está certo, eu não pensei em privilégios de root. Isso pode levar a erros, uma vez que você ainda recebe uma resposta quando não está na raiz, mas é diferente (portanto, você deve ser cauteloso ao contar com eles wc -l). Bem, eu aceitarei a resposta de Hauke ​​Laging e darei-lhe um voto positivo . ;)
Totor
1

Você também pode apenas analisar a pssaída e procurar nomes de processos que não estão entre colchetes:

ps aux | awk '$NF!~/^\[.+\]$/'
terdon
fonte
Uma maneira um pouco menos confiável de obter a lista de usuários nos quais você está interessado: 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.
Keith Thompson
Bah, você está certo o tempo todo, @KeithThompson, removeu os outros, eles não valem a pena. Você poderia me ajudar a limpar os (agora) comentários obsoletos?
terdon
2
Observe que $NFé a última palavra da linha de comando na ps auxsaí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.
Stéphane Chazelas
1

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
Russ
fonte
0

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.

Joshua Huber
fonte
0

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 pscomando é que ele inclui apenas filhos diretos, mas nem todos os descendentes. O pstreecomando inclui todos os descendentes. Você pode comparar e contar a saída desses dois comandos (é uma maneira fácil de usar | wc) para verificar.

ssppjj
fonte