killall mi dà `nessun processo trovato` ma ps


17

Qualcuno potrebbe spiegarmi la differenza tra kille killall? Perché non killallvede ciò che psmostra?

# ps aux |grep db2
root      1123  0.0  0.8 841300 33956 pts/1    Sl   11:48   0:00 db2wdog                                         
db2inst1  1125  0.0  3.5 2879496 143616 pts/1  Sl   11:48   0:02 db2sysc                                        
root      1126  0.0  0.6 579156 27840 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1127  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd                                        
root      1128  0.0  0.6 579156 27828 pts/1    S    11:48   0:00 db2ckpwd 

# killall db2ckpwd
db2ckpwd: no process found

# kill -9 1126
# kill -9 1127
# kill -9 1128

Il sistema è SuSe 11.3 (64 bit); kernel 2.6.34-12; procps versione 3.2.8; killall da PSmisc 22.7; uccidere da GNU coreutils 7.1


Non uccidere mai i processi con SIGKILL (-9).
vonbrand,

Cosa fare quando un processo deve essere terminato?
Radek,

Questa è l'ultima, ultima risorsa.
vonbrand,

Risposte:


19

È su Linux?

Ci sono in realtà un paio di versioni leggermente diverse del nome del comando che vengono utilizzati dai ps, killallecc

Le due varianti principali sono: 1) il nome del comando lungo, che è quello che ottieni quando corri ps u; e 2) il nome breve del comando, che è quello che ottieni quando corri pssenza flag.

Probabilmente la differenza più grande si verifica se il tuo programma è uno script di shell o qualcosa che richiede un interprete, ad esempio Python, Java, ecc.

Ecco uno script davvero banale che dimostra la differenza. L'ho chiamato mycat:

#!/bin/sh
cat

Dopo averlo eseguito, ecco i due diversi tipi di ps.

Innanzitutto, senza u:

$ ps -p 5290
  PID TTY      ... CMD
 5290 pts/6    ... mycat

In secondo luogo, con u:

$ ps u 5290
USER       PID ... COMMAND
mikel     5290 ... /bin/sh /home/mikel/bin/mycat

Nota come inizia la seconda versione /bin/sh?

Ora, per quanto posso dire, in killallrealtà legge /proc/<pid>/state prende la seconda parola tra le parentesi come nome del comando, quindi è proprio quello che devi specificare quando corri killall. Logicamente, dovrebbe essere lo stesso di quello che dice pssenza la ubandiera, ma sarebbe una buona idea controllare.

Cose da controllare:

  1. cosa cat /proc/<pid>/statdice il nome del comando è?
  2. cosa ps -e | grep db2dice il nome del comando è?
  3. fare ps -e | grep db2e ps au | grep db2mostrare lo stesso nome comando?

Appunti

Se stai usando anche altri flag ps, potresti trovare più semplice usare ps -o commper vedere il nome breve e ps -o cmdper vedere il nome lungo.

Potresti anche trovare pkillun'alternativa migliore. In particolare, pkill -ftenta di eseguire la corrispondenza utilizzando il nome completo del comando, ovvero il nome del comando stampato da ps uo ps -o cmd.


ottima spiegazione. E immagino tu abbia ragione la prima volta. ps -e |grep db2 gives me 3084? 00:00:00 db2syscr` e ps aux | grep db2 mi danno root 3084 0.0 0.6 579292 28304 ? S 13:02 0:00 db2ckpwd. Potrei commentarlo. Mi sono perso un po '.
Radek,

Non ne sono sicuro. È possibile che il programma stia cambiando il suo nome. Sai come viene eseguito? Cosa ls -l /proc/3084/exedice? Che dire whicho whenceo typeper trovare il file e quindi lse typeper vedere se si tratta di un collegamento simbolico o uno script o un file binario?
Mikel,

ls -l / proc / 3084 / exe ci dàlrwxrwxrwx 1 root root 0 Jun 6 16:49 /proc/3084/exe -> /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek il

ls -l / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr mi dà-r-sr-s--- 1 root db2iadm1 147K Feb 1 23:32 /var/lib/db2/db2inst1/sqllib/adm/db2syscr*
Radek,

type mi dà / var / lib / db2 / db2inst1 / sqllib / adm / db2syscr/var/lib/db2/db2inst1/sqllib/adm/db2syscr is /var/lib/db2/db2inst1/sqllib/adm/db2syscr
Radek

6

killall tenta di abbinare un nome di processo (ma non è poi così bravo nella parte corrispondente).

E poiché "ps | grep" e "ps | grep | kill" fanno un lavoro molto migliore, qualcuno lo ha semplificato e ha creato pgrep e pkill. Leggi che comandi come "ps grep" e "ps kill", dal momento che quel comando prima ps poi grep e se vuoi uccidere.


2

Ho avuto un problema simile ma /proc/<pid>/statcontenevo la stringa prevista. Usando strace ho potuto vedere anche l'accesso a killall /proc/<pid>/cmdline.

Ho continuato a indagare usando gdb per scoprire che nel mio caso non è riuscito a controllare il mio comando per il comando completo, inclusi tutti gli argomenti trovati in /proc/<pid>/cmdline. Sembrava quel percorso del codice attivato a causa del fatto che il nome del file era più lungo di 15 caratteri (che è un valore hardcoded nella fonte di killall). Non ho studiato a fondo se in qualche modo riuscissi a farlo funzionare con killall.

Ma come menzionato in altri commenti qui pkill è un'alternativa migliore che non ha gli stessi problemi.

Il codice sorgente di pkillpuò essere trovato qui https://github.com/acg/psmisc per gli interessati.


0

Sui sistemi Ubuntu 16 / proc / pid / stat conterrà il nome del thread (che un programma può tramite la chiamata di sistema pthread_setname_np .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.