PDA

Visualizza la versione completa : Killare processi duplicati utente


magnus
07-08-2009, 19:40
Ciao Ragazzi,
avrei bisogno di realizzare uno script che limiti il numero di processi "java" attivi per utente riducendoli ad uno solo per volta...
Mi spiego meglio...
Mettiamo che lanci: ps -A

Avrei:

PID TTY TIME CMD
697 ? 00:24:45 java
711 ? 00:07:54 java
1398 ? 00:00:16 java
2030 ? 00:00:00 scsi_eh_0
ecc...

prima di tutto dovrei avere una lista più simile a questa ( ciò in cui viene incluso il nome utente ):

PID USER TIME CMD
697 pippo 00:24:45 java
711 pippo 00:07:54 java
1398 pluto 00:00:16 java
2030 paperino 00:00:00 scsi_eh_0

Successivamente mediante un comando dovrei riuscire a killare il processo duplicato "java" per pippo ( in questo caso il 711 - il secondo processo "java" per l'utente pippo ), poichè "pippo" può aprire un solo processo java per volta...

Come fare?

Ciao! :)

YuYevon
07-08-2009, 22:06
Questo dovrebbe andare



#!/bin/sh

if [ "$#" -ne 1 ]
then
echo "usage: $0 <process_name>"
exit 1
fi

lines=`ps -A | awk /"$1"$/'{print $1}' | wc -l | cut -d " " -f 1`

if [ "$lines" -gt 1 ]
then
kill `ps -A | awk /"$1"$/'{print $1}' | head -$(($lines-1))`
fi

exit 0


va richiamato da shell col nome del processo di cui eliminare i doppioni, nel tuo caso



$ nome_script.sh java


ti consiglio vivamente di non sbagliare a scrivere la stringa in input... ;D

Questo però elimina tutti i doppioni senza badare all'utente che ha avviato il processo... volevo sapere: come va deciso di quale utente vanno eliminati i doppioni? E' un nome fisso (tipo "pippo" appunto) o cambia di volta in volta? In ogni caso basterebbe cambiare il comando ps aggiungendo l'opzione -U nome_utente, ma specifica meglio questo punto...

magnus
09-08-2009, 02:06
Ciao,
a me non servirebbe semplicemente eliminare tutti i doppioni...
Mi servirebbe eliminare i doppioni per utente...

YuYevon
09-08-2009, 10:29
Allora bastano semplicemente queste modifiche:



#!/bin/sh

if [ "$#" -ne 2 ]
then
echo "usage: $0 <process_name> <user_name>"
exit 1
fi

lines=`ps -U $2 | awk /"$1"$/'{print $1}' | wc -l | cut -d " " -f 1`

if [ "$lines" -gt 1 ]
then
kill `ps -U $2 | awk /"$1"$/'{print $1}' | head -$(($lines-1))`
fi

exit 0


e richiamare lo script ad esempio così



./nome_script java pippo


Ovviamente assicurati che l'utente che lancia lo script abbia i privilegi necessari per ammazzare i processi "incriminati"...

magnus
09-08-2009, 10:54
Potrebbe essere una soluzione, però considera che non so a priori l'utente che sta duplicando i processi...
Quindi lo script dovrebbe determinare automaticamente l'utente che sta duplicando quel determinato processo e killare tutti quelli che gli appartengono tranne uno.

Altrimenti dovrei lanciare lo script per ogni utente presente nel sistema ogni volta :confused:

YuYevon
09-08-2009, 11:19
Ecco, proprio per questo chiedevo delucidazioni sulla scelta dell'utente in uno dei post precedenti...


Originariamente inviato da magnus
Altrimenti dovrei lanciare lo script per ogni utente presente nel sistema ogni volta :confused:

Vabbè questo non è un problema dato che si può automatizzare tranquillamente. Vedi se questo va bene... l'ideale (in termini di tempo) sarebbe trovare gli utenti che hanno effettivamente processi duplicati e lavorare solo su quelli, ma si tratterebbe di fare modifiche troppo contorte allo script di prima.



#!/bin/bash

if [ "$#" -ne 1 ]
then
echo "usage: $0 <process_name>"
exit 1
fi

user_list=`cat /etc/shadow | cut -d ":" -f 1`

for user_name in $user_list; do

lines=`ps -U $user_name | awk /"$1"$/'{print $1}' | wc -l | cut -d " " -f 1`

if [ "$lines" -gt 1 ]
then
kill `ps -U $user_name | awk /"$1"$/'{print $1}' | head -$(($lines-1))`
fi
done

exit 0


Si presume chiaramente che chi avvia il processo sia un amministratore. Stavolta comunque basta scrivere

# ./nome_script.sh <nome_processo>

visto che verrà eseguito per tutti gli utenti.

magnus
09-08-2009, 18:23
#!/bin/bash

if [ "$#" -ne 1 ]
then
echo "usage: $0 <process_name>"
exit 1
fi

user_list=`cat /etc/shadow | cut -d ":" -f 1`

for user_name in $user_list; do

lines=`ps -U $user_name | awk /"$1"$/'{print $1}' | wc -l | cut -d " " -f 1`

if ![ "$user_name" = "root" ]
then
if [ "$lines" -gt 1 ]
then
kill `ps -U $user_name | awk /"$1"$/'{print $1}' | head -$(($lines-1))`
fi
fi
done

exit 0



Mi pare ottimo il tuo script... per non applicare la regola all'user root è corretta la modifica che ho riportato?

:ciauz:

YuYevon
09-08-2009, 18:58
Potrebbe andare bene ma devi separare ! e [, altrimenti bash interpreterà ![ come un unico operatore o comando e ti dirà ![: command not found

Puoi anche scrivere così



if [ ! "$user_name" = "root" ]


o meglio ancora così



if [ "$user_name" != "root" ]


hint: quando posti codice, usa i tag "code" non "quote" altrimenti si perde l'indentazione ;)

magnus
09-08-2009, 19:02
Grazie mille per il supporto!!! :ciauz:

magnus
09-09-2009, 23:31
Avrei un'ultima esigenza, cioè quella di killare tutti i processi tranne uno ma che però sia il più recente...

In pratica lo script va bene, però dovrebbe rimanere attivo il processo di quel tipo più recente ( cosa che non sempre avviene ).

Come potrei modificare lo script?

Ciao!

Loading