Come posso chiedere ps
di visualizzare solo i processi utente e non i thread del kernel?
Vedi questa domanda per vedere cosa intendo ...
Come posso chiedere ps
di visualizzare solo i processi utente e non i thread del kernel?
Vedi questa domanda per vedere cosa intendo ...
Risposte:
Questo dovrebbe fare (sotto Linux):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) ha PPID 0 ( su Linux 2.6+ ) ma ps
non consente di filtrare per PPID 0; quindi questo aggirare.
kthreadd
, quindi crea la ps
chiamata corrispondente. Quanto è garantito che questa cosa sarà "sempre" chiamata "kthreadd"? Una soluzione sicura sarebbe più complicata, funzionerebbe ps
normalmente e analizzerebbe l'output, magari facendo alcuni test.
x
bandiera che non funziona con questo. ps au --ppid 2 -p 2 --deselect
funziona bene.
Un modo per riconoscere i processi del kernel è che non usano alcuna memoria utente, quindi il campo vsz è 0. Questo cattura anche gli zombi (grazie a Stephane Chazelas per questa osservazione), che possono essere eliminati in base al loro stato.
ps axl | awk '$7 != 0 && $10 !~ "Z"'
Per elencare solo i PID:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
In pratica ho trovato abbastanza il seguente linguaggio:
ps auxf | grep -v ]$
Filtra le linee che terminano con parentesi, che potrebbe comportare l'omissione di voci indesiderate, ma è molto improbabile. In cambio è abbastanza facile da ricordare e relativamente veloce da digitare.
Alcuni processi come avahi-daemon aggiungono tra parentesi le informazioni sul nome del processo (il nome host nel caso di avahi-daemon) e verranno filtrati da questo comando.
Una delle particolarità di questi processi è che non sono supportati da un file eseguibile, quindi potresti farlo ( in zsh ):
ps /proc/[0-9]*/exe(^-@:h:t)
O con qualsiasi shell POSIX:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
Cioè controlla i processi il cui /proc/<pid>/exe
è un collegamento a un file.
Ciò significa che devi essere un superutente per poter controllare lo stato del /proc/<pid>/exe
link simbolico.
Modifica : Come accade, i processi di zombi (almeno) soddisfano la stessa condizione, quindi se non li vuoi escludere, dovresti aggiungerli di nuovo. Piace:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
Nota che ps -f
mostra quei nomi di processo tra parentesi quadre non perché sono processi del kernel, ma perché hanno un vuoto argv[]
(quindi ps mostra il nome del processo anziché argv[0]
lì). Puoi avere un processo dello spazio utente anche con un vuoto argv[]
e puoi avere un nome di processo con una argv[0]
forma che è [some-string]
quindi un filtro ps
dell'output basato su quelle parentesi quadre non è un'opzione infallibile.
zsh
sintassi. Il secondo è la sintassi POSIX standard sh
(e ps
e find
e cut
e paste
). Ovviamente /proc
non è specificato da POSIX.
wc -l
). Bene, accetterò la risposta di Hauke Laging e ti darò un voto. ;)
Puoi anche analizzare l' ps
output e cercare i nomi dei processi che non sono tra parentesi:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
- ma otterrai comunque processi che menzionano un tale nome utente e lascerai il file temporaneo in giro. Ritiro il mio voto negativo, ma solo perché la tua terza soluzione è ragionevole.
$NF
è l'ultima parola della riga di comando ps aux
nell'output. I processi non kernel possono avere [...]
lì. Come ho detto nella mia risposta, la [xxx]
notazione non è perché sono processi del kernel, ma perché non hanno una riga di comando (nessun argomento) che è consentita anche per i processi non kernel.
Per chiunque provi questo in busybox dove ps
è fortemente semplificato e l'output è diverso, questa variante della grande risposta di Gilles funziona bene:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
Secondo la risposta di Gilles, la metodologia qui è quella di trovare processi che non usano alcuna memoria utente (`vsz col == 0) e filtrare i processi zombie (lo stato col non è 'Z').
Le colonne di output possono essere regolate facilmente, purché i numeri dei campi awk basati su 1 siano adeguati di conseguenza. Vedi le opzioni che il tuo ps ha a disposizione inserendo un valore falso e te lo dirà. Per esempio:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Se hai solo bisogno dei conteggi ... Avevo un'analoga necessità di filtrare i processi kernel vs user, ma avevo solo bisogno dei rispettivi conteggi di ciascuno. Questa era la mia soluzione:
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]}'
Uscita campione :
Kernel processes 353
User processes 52
Total processes 405
Spiegazione : Sto usando l'hacking che i processi VSZ = 0 possono essere considerati processi del kernel. Quindi awk
, valuto un confronto su VSZ (da ps -eo vsize
), sia uguale a zero. Il risultato del confronto sarà uno 0 booleano o 1. Faccio un array p[]
e, mentre corro l'elenco dei processi, se è un processo del kernel, incremento p[1]++
. Altrimenti, come processo utente, aumento p[0]++
. Dopo tutto l'incremento, etichetta e stampa i valori (ovvero i conteggi) per p [0] e p [1] nel END { }
blocco.
Quello che stai cercando, amico mio, non lo è ps
, mapstree
.
Innanzitutto, identifica il primo processo del kernel. Il suo PID è comunemente 1 sul sistema senza systemd e 2 con systemd.
Quindi utilizzare questo comando:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
La risposta selezionata (una con ✅) sta usando un altro comando:
$ ps --ppid 2 -p 2 --deselect
Il problema con questo ps
comando è che include solo figli diretti ma non tutti i discendenti. Il pstree
comando include tutti i discendenti. Puoi confrontare e contare l'output di questi due comandi (un modo semplice sta usando | wc
) per verificare.
kthreadd
sia sempre PID 2?