2009-11-24 7 views
4

La scrip shell suivante vérifier l'espace disque et changer la variable diskfull-1 si l'utilisation est plus de 10% Le dernier écho montre toujours 0 J'ai essayé le global diskfull=1 dans la clause if mais n'a pas fonctionné. Comment modifier la variable à 1 si le disque consommé est supérieur à 10%?portée de la variable dans le tuyau

#!/bin/sh 
diskfull=0 

ALERT=10 
df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk '{ print $5 " " $1 }' | while read output; 
do 
    #echo $output 
    usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) 
    partition=$(echo $output | awk '{ print $2 }') 
    if [ $usep -ge $ALERT ]; then 
    diskfull=1 
    exit 
    fi 
done 

echo $diskfull 
+0

Etes-vous sûr que le corps de l'instruction if est en cours d'exécution? Plus que probable, if est en train d'évaluer false et la ligne diskfull = 1 n'est jamais exécutée. – asm

+0

Merci pour toutes les réponses.Ce que j'ai fait, c'est que j'ai quitté la clause if avec le statut de sortie 1, puis sauvegardé cette variable dans diskfull immédiatement après "done". Cette solution de contournement semble fonctionner. – shantanuo

Répondre

1

Lors de l'utilisation de tuyaux, la coque sert à utiliser des sous-coques pour effectuer le travail. Comme $diskfull n'est pas connu de ces sous-shells, la valeur n'est jamais changée.

Voir: http://www.nucleardonkey.net/blog/2007/08/variable_scope_in_bash.html

I modifié votre script comme suit. Cela fonctionne pour moi et devrait fonctionner sur votre système aussi.

#!/bin/sh 
diskfull=0 

ALERT=10 
stats=`df -HP | grep -vE '^Filesystem|tmpfs|cdrom|none|udev' | awk '{ print $5 "_" $1 }'` 
for output in $stats 
do 
    usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) 
    partition=$(echo $output | sed s/.*_//) 
    #echo $partition - $usep 
    if [ $usep -le $ALERT ]; then 
    diskfull=1 
    break 
    fi 
done 
echo $diskfull 
0

Je pense que vous ne devez pas être trouvé à la ligne diskfull=1, parce que si vous étiez, vous obtenez pas de sortie à all-- la ligne suivante exit disparaîtrait du script.

Je ne sais pas pourquoi cela ne fonctionne pas, mais notez que awk peut gérer le reste du travail:

diskfull=$(df -HP | grep -vE '^Filesystem|tmpfs|cdrom' | awk 'BEGIN { x = 0 } { if ($5 + 0 >= '$ALERT') { x = 1 } } END { print x }') 

De cette façon, vous n'avez pas besoin de la boucle while.

0

vous pouvez le faire de cette façon avec gawk (pas besoin d'utiliser grep). pour les alertes, vous pouvez envoyer un email à root.

threshold=10 
df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{ 
    msg=msg $1" is "$5"\n" 
}END{print msg}' | mail root 

ou vérifier s'il y a "msg" ou non premiers

threshold=10 
result=$(df -HP | awk -v t="$threshold" -v msg="" 'NR>1 && $5+0 > t{ 
    msg=msg $1" is "$5"\n" 
}END{print msg}') 
if [ -n "$result" ];then 
    echo "Overload" 
    echo "$result" | mail root 

fi 
0

Dans cette ligne:

usep=$(echo $output | awk '{ print $1}' | cut -d'%' -f1 ) 

ce n'est pas nécessaire d'utiliser cut. Vous pouvez le faire:

usep=$(echo $output | awk -F% '{ print $1}') 
+0

en utilisant gawk, vous pouvez utiliser $ 5 + 0 pour changer le champ en entier. Le% est "parti automatiquement". (par manque de meilleur mot) – ghostdog74

1

@OP, utilisez une attelle externe ou()

count=0 
max=10 
diskfull=0 
df -HP | { while read disk b c d used e 
do  
    if [ "$count" -gt 1 ];then 
     used=${used%?} 
     if [ "$used" -gt "$max" ];then 
      echo "overload: $disk, used: $used%" 
      diskfull=1 
     fi 
    fi 
    count=$((count+1)) 
done 
echo "diskfull: $diskfull" 
} 
5

Ceci est un effet secondaire de l'utilisation while dans un pipeline. Il existe deux solutions de contournement:

1) mettre la boucle while et toutes les variables qu'il utilise dans un cadre à part entière comme l'a démontré levislevis86

some | complicated | pipeline | { 
    while read line; do 
     foo=$(some calculation) 
    done 
    do_something_with $foo 
} 
# $foo not available here 

2) si votre shell le permet, utiliser substitution de processus et vous pouvez rediriger la sortie de votre pipeline vers l'entrée de la boucle while

while read line; do 
    foo=$(some calculation)} 
done < <(some | complicated | pipeline) 
do_something_with $foo 
+0

Vous pouvez essayer ['set + o posix'] (http://www.linuxjournal.com/content/shell-process-redirection) avant 2). Regardez aussi [ici] (http://tldp.org/LDP/abs/html/process-sub.html). – sjngm