[script] contre la fuite memoire

Autres projets et contributions
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

[script] contre la fuite memoire

Message par cassyb »

salut,

Certaines applications (navigateurs web, telechargement, video, voire même le terminal quand il regarde un enorme log) provoque l'instabilité du système en nous obligeant à rebooter comme un bourrin.

Je voulais savoir le nom d'un paquet qui surveillerait les processus et si %mem et %CPU sont supérieur à un certains seuil pendant 4-5 secondes ça envoit un popup pour nous permettre de continuer l'execution du programme ou bien de le killer.

S'il n'existe pas pouvez-vous m'aider à la creation d'un script.
3 paramètres:
- Nbseconds
- mem_seuil
- cpu_seuil

Algo:
- lancer top
- regarder pendant Nbseconds si un process est au dessus de mem_seuil ou cpu_seuil
- si c'est le cas, ça envoie un popup: L'application "nom_application" rend votre système instable. Voulez-vous killer cette application?
- en cliquant sur le bouton killer, ça lance un kill -9 du pid ou un killall de l'application.

Mais est-il possible de s'envoyer un popup via un script sh?
merci pour votre aide.

a+
Cassy.
Dernière modification par cassyb le jeu. 08 nov. 2007, 13:40, modifié 10 fois.
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

Oui envoyer un popup c'est possible de différentes manières. La plus simple qui me vient à l'esprit est d'utiliser xdialog.

Sinon au lieu d'utiliser top, je te conseille plutôt "ps". Rien qu'avec "grep" et "cut" tu pourra réaliser ce que tu souhaites.
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

b'hein top ça evite de lancer Nbseconds fois la commande ps non?
c'est pour ça que je pensais à top plutôt qu'à ps.
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

Je vois pas trop comment récupérer les infos de top... et puis faire tourner top en permanence ça doit pas etre rentable en terme de ressources consommées.
L'idéal serait peut-etre de taper dans /proc directement ?
un peu d'aide: http://forums.archlinux.fr/topic854.html
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

je suis aller voir ton lien...mais je ne vois pas trop comment je pourrais utiliser /proc (déjà que j'ai du mal avec ps)

j'arrive pas à classer le %mem ou %cpu en ordre décroissant.
sur un site j'ai vu qu'ils utilisent le champ rss, je ne sais pas si c'est un bon indicateur:
ps aux --sort:-rss

comment ferais-tu pour classer suivant %mem et %cpu décroissant.
et comment récupérer juste la 2ème ligne du ps c'est à dire l'application qui occupe le + de mémoire?

merci.
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

bon j'y suis presque.
mais j'arrive pas à créer une variable dynamiquement.
genre

APPLICATION_CPU='blabla'
echo $APPLICATION_CPU
renvoie blabla

EXT ='_CPU'
echo ${APPLICATION$EXT}
j'ai droit à un bad substitution
comment faire pour qu'il renvoie blabla?
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

Bon j'ai fait sans tant pis.

Aussi j'ai des pb d'accents, ça affiche des hieroglyphes...du coup j'ai fait en sorte qu'il n'y ait pas d'accents.

noMemoryLeak s'utilise avec un raccourci clavier.
Peut s'utiliser avec une crontab mais faut modifier le script en spécifiant un seuil de %mem et %cpu.

Code : Tout sélectionner

#!/bin/sh

#sources:
#http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1248880,00.html
#http://xdialog.dyns.net/

#quelle application occupe le + en %mem
RESULT_MEM=$( ps -eo pmem,pid -o comm= | sort -k1 -n -r | head -1)
P_MEM=$( echo $RESULT_MEM | cut -d' ' -f1)
PID_MEM=$( echo $RESULT_MEM | cut -d' ' -f2)
APPLICATION_MEM=$( echo $RESULT_MEM | cut -d' ' -f3)

#quelle application occupe le + en %cpu
RESULT_CPU=$( ps -eo pcpu,pid -o comm= | sort -k1 -n -r | head -1)
P_CPU=$( echo $RESULT_CPU | cut -d' ' -f1)
PID_CPU=$( echo $RESULT_CPU | cut -d' ' -f2)
APPLICATION_CPU=$( echo $RESULT_CPU | cut -d' ' -f3)

# si c'est la même application qui occupe le + de mem et cpu
if [ $PID_CPU -eq $PID_MEM ]
then 
	CHOICE=`Xdialog --default-no --title "noMemoryLeak" \
        --checklist "Voulez-vous killer cette application?" 9 50 0 \
        "$PID_MEM"  "$APPLICATION_MEM utilise ${P_MEM}%mem et ${P_CPU}%cpu" on 2>&1`
else
	CHOICE=`Xdialog --default-no --title "noMemoryLeak" \
        --checklist "Voulez-vous killer ces applications?" 11 40 0 \
        "$PID_MEM"  "$APPLICATION_MEM utilise $P_MEM %mem" on \
        "$PID_CPU"  "$APPLICATION_CPU utilise $P_CPU %cpu" on 2>&1`
fi

case $? in
	0)
		# si au moins une checkbox cochee
		if [ $CHOICE ]
		then
			# doit-on killer une ou deux applications?
			if [ $( echo $CHOICE | cut -d'/' -f1) -eq $( echo $CHOICE | cut -d'/' -f2) ]
			then
				kill -9 $CHOICE
			else
				kill -9 $( echo $CHOICE | cut -d'/' -f1)
				kill -9 $( echo $CHOICE | cut -d'/' -f2)
			fi
			echo "killed."
		else
			echo "none killed."
		fi;;
	1)
		echo "Cancel pressed.";;
	255)
		echo "Box closed.";;
esac
Dernière modification par cassyb le dim. 26 août 2007, 16:21, modifié 6 fois.
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

ça a l'air déjà pas mal, sauf la boite de dialogue qui ne s'affiche pas chez moi.

J'ai pas pigé ce que tu veux dire par "créer une variable dynamiquement." ?
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

ça a l'air déjà pas mal, sauf la boite de dialogue qui ne s'affiche pas chez moi.
Tu connais l'histoire du gars qui conseille xdialog pour sa simplicité mais qui en fait ne l'a jamais installé? :wink:

t'as quelle erreur precisément?

variable dynamique...mais si quand le contenu d'une variable est elle même une variable...comme en php genre $$variable...

APPLICATION_CPU='blabla'
je voulais construire dynamiquement le nom de la variable APPLICATION_CPU ainsi:
${APPLICATION$EXT}
$EXT correspondant à _CPU ou à _MEM

je voulais faire la concatenation de APPLICATION et de _CPU donnant APPLICATION_CPU qui se trouve être cette variable contenant 'blabla'.
ça aurait economisé 4 lignes...pas bien grave.
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

cassyb a écrit :
ça a l'air déjà pas mal, sauf la boite de dialogue qui ne s'affiche pas chez moi.
Tu connais l'histoire du gars qui conseille xdialog pour sa simplicité mais qui en fait ne l'a jamais installé? :wink:

t'as quelle erreur precisément?

variable dynamique...mais si quand le contenu d'une variable est elle même une variable...comme en php genre $$variable...

APPLICATION_CPU='blabla'
je voulais construire dynamiquement le nom de la variable APPLICATION_CPU ainsi:
${APPLICATION$EXT}
$EXT correspondant à _CPU ou à _MEM

je voulais faire la concatenation de APPLICATION et de _CPU donnant APPLICATION_CPU qui se trouve être cette variable contenant 'blabla'.
ça aurait economisé 4 lignes...pas bien grave.
t'inquiète xdialog est bien là... c'est ton script qui foire:

Code : Tout sélectionner

Xdialog: missing box option !
Les variable dynamique ça n'existe pas en bash. Mais d'après ce que tu décrit, un tableau devrait faire l'affaire.
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

peut être le copié-coller qui a foiré.
Essaye avec le script du site officiel, j'ai pris leur syntaxe.
http://xdialog.dyns.net/
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

J'ai remarqué dans mon ~ que j'avais plein de fichier genre 7.4, 7.9, etc...

Le pb est ici:
if [ $P_MEM > $P_CPU ]

il ne fait pas la comparaison mais ecrit dans le fichier $P_CPU...
j'ai modifier en
if [[ $P_MEM > $P_CPU ]]

si je compare 32.4 à 5.6 il me dit que 5.6 est plus grand. :roll:
il doit faire une compraison de string...
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

bon j'ai fait autrement.
J'en ai profité pour améliorer le script en laissant au choix à l'utilisateur de killer soit l'application la + gourmande en cpu, soit en mem soit les deux.

le script se trouve ici.
_alexmyself
Chu Ko Nu
Messages : 405
Inscription : lun. 18 sept. 2006, 16:21
Localisation : france, yvelines 78

Message par _alexmyself »

pour pouvoir faire des calculs/comparaisons sur des nombres:

typeset -i mavarnombre=10

comme ça c'est un nombre et plus une chaine
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

J'aurais une autre question...
j'écris un autre script

Code : Tout sélectionner

PROCESS_LIST=`ps -eo user,pid -o comm= | grep rsync`
me retourne une liste genre:
root 28398 rsync

Code : Tout sélectionner

for process in $PROCESS_LIST
do
 echo $process
done
ça me renvoie:
root
28398
rsync
comment faire pour qu'il conserve la ligne?
pour que je puisse faire

Code : Tout sélectionner

USER=`echo $process | awk '{print $1}'`
PID=`echo $process | awk '{print $2}'`
PNAME=`echo $process | awk '{print $3}'`
merci.
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

Salut Cassyb

Si ton grep ne te renvoie qu'une seule ligne, alors tu peux utiliser ta variable comme un tableau.

Code : Tout sélectionner

USER=${PROCESS_LIST[0]}
PID=${PROCESS_LIST[1]}
PNAME=${PROCESS_LIST[2]}
si tu veux traiter chacune des lignes (l'une après l'autre), tu peux aussi utiliser la syntaxe "while read":

Code : Tout sélectionner

ps -eo user,pid -o comm= |
while read line; do
    USER=${line[0]}
    PID=${line[1]}
    PNAME=${line[2]}
    echo "$USER :  pid=$PID pname=$PNAME"
done
Mais ça dépend de ce que tu veux faire :)
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

alors tu peux utiliser ta variable comme un tableau
et ça split automatiquement ma ligne en tableau?
parce que
PID=${line[1]}
PNAME=${line[2]}
c'est vide chez moi avec bash, sh :shock:
line[0] contient en fait toute la ligne
en gros ça me renvoit ça:
cassy 7346 epiphany : pid= pname=
...
Avatar de l’utilisateur
wain
Maître du Kyudo
Messages : 1854
Inscription : ven. 11 août 2006, 19:15
Localisation : Nancy (54)

Message par wain »

ah oui ça split pas pardon. Faut ajouter ligne=( $ligne ) avant
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

nikel merci.
Avatar de l’utilisateur
cassyb
Chu Ko Nu
Messages : 310
Inscription : jeu. 04 janv. 2007, 09:07

Message par cassyb »

Juste une question...

Code : Tout sélectionner

ligne=( $ligne ) 
permet par défaut de spliter sur un espace mais si on veut que ça split sur un tiret par exemple t'écrirais ça comment?
Répondre