web-dev-qa-db-fra.com

si condition avec la taille du répertoire du serveur distant

J'écris un petit script pour télécharger les fichiers sur un serveur ssh distant et sur le serveur ssh distant, il me restera presque 2 TB of Space.

J'ai besoin de vérifier dans le script Shell si l'espace est autour de 1.5 TB plein que sleep the script et **start the script again** une fois qu'il revient, il retourne à 1TB

voici ma partie du code qui doit exécuter la logique de vérification de la taille du répertoire, puis l'insérer dans le if else statements

SIZE="$(ssh archiveupload@REMOTESERVER-IP "du -s")"
LIMIT="1.5TB"
if [ $SIZE -gt $LIMIT ];
then
  sleep 4h
Elif
 continue ;
fi

UPDATE SCRIPT:

if [ ! -f /home/user/Tupload/upload-lock ]; then
    touch /home/user/Tupload/upload-lock
    ###Define the File in unix style#############
    filename="/home/user/Tupload/20186.txt"
    ####starting of the while loop.###########
    LIMIT='1500000000'
    while read line;
    do
        name="${line%$'\r'}"
        SIZE="$(ssh -n USER@REMOTEIP"df /var/www/Upload/" | awk 'NR > 1 {print $4; exit}')"

        if [[ $SIZE -gt $LIMIT ]]
        then
            YEAR=$(echo $name | cut -c 1-4)   #####define the Year from the read line ####
            MONTH=$(echo $name | cut -c 5-6)  #####Define the Month from the read line####
            DAY=$(echo $name | cut -c 7-8)  #####Define the DAY from the read line####
            YM=${YEAR}-${MONTH} ####define the Year and Month######

            april="2017-04"
            may="2017-05"
            june="2017-06"
            march="2017-03"
            ######if else statement ######
            if [ "$april" = "$YM"  ]; then
                cd /mnt/smxfxml/$YEAR/April/
            Elif [ "$may" = "$YM"  ]; then
                cd /mnt/smxfxml/$YEAR/May/
            Elif [ "$june" = "$YM"  ]; then
                cd /mnt/smxfxml/$YEAR/June/
            Elif [ "$march" = "$YM"  ]; then
                cd /mnt/smxfxml/$YEAR/March/
            else
                cd /mnt/smxfxml/$YEAR/$YM/
            fi

            ssh USER@REMOTEIP"mkdir $YEAR/$MONTH/$DAY/$name/" < /dev/null
            scp $name.mxf USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
            cd /mnt/smxfxml/XML/$YEAR/$YM/
            scp $name.xml USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
        else 
            echo 'Not enough space.'; sleep 4h
        fi
    done <"$filename"
    rm -rf /home/user/Tupload/upload-lock
    exit 0
else
    sleep 0 
fi
exit 0
2
kunal

Merci à pa408 pour l’espace libre "one liner".


Maintenant que vous avez partagé votre script:

Cela va être un peu plus difficile car nous ne pouvons pas utiliser continue à l'intérieur de la boucle while read line sans sauter de lignes.

Vous souhaitez suspendre le script lorsqu'il n'y a pas plus de 0,5 To disponible, et reprendre lorsqu'il y a au moins 1 To disponible.

Pour que le script soit court et lisible par l'homme, définissez une fonction qui vous indique s'il y a suffisamment d'espace sur le serveur et prend la taille minimale en tant que paramètre:

enough_space () {
    local limit=$1
    free_space="$(ssh -n user@Host "df /" | awk 'NR > 1 {print $4; exit}')"
    [ $free_space -ge $limit ]
}

... et soit dormez sans assez d'espace :

while ! enough_space $limit; do
    sleep 4h
done

... ou dormez jusqu'à ce que ait suffisamment d'espace :

until enough_space $limit; do
    sleep 4h
done

Incorporer ceci dans votre script

Mettez ceci au début de votre script:

pause_limit='500000000'    # 0.5TB free space
resume_limit='1000000000'  # 1.0TB free space

enough_space () {
    local limit=$1
    free_space="$(ssh -n user@Host "df /" | awk 'NR > 1 {print $4; exit}')"
    [ $free_space -ge $limit ]
}

Nous allons introduire une boucle "infinie" while à l'intérieur de la boucle existante while. Cela nous permet de réessayer le même fichier lorsqu'il n'y avait pas assez d'espace libre la première fois. En outre, l'affectation des variables ne dépend pas de l'espace disponible sur le serveur. Par conséquent, il doit être conservé en dehors de l'instruction if (et de la boucle intérieure while).

####starting of the while loop.###########
while read line; do 
#### this can all be done before checking the server's free space
#    name="${line%$'\r'}"
#    YEAR=$(echo $name | cut -c 1-4) 
#      .
#      .
    ######if else statements ######
#    if [ "$april" = "$YM"  ]; then
#      .
#      .
#    fi

    while true; do
        if enough_space $pause_limit;
        then
            ssh USER@REMOTEIP"mkdir $YEAR/$MONTH/$DAY/$name/" < /dev/null
            scp $name.mxf USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
            cd /mnt/smxfxml/XML/$YEAR/$YM/
            scp $name.xml USER@REMOTEIP:$YEAR/$MONTH/$DAY/$name/
            break
        else
            until enough_space $resume_limit; do
                sleep 4h
            done
        fi
    done
done <"$filename"

La boucle while "infinie" sera exécutée une fois (s'il y a suffisamment d'espace libre sur le serveur) ou deux fois (s'il en reste suffisamment).


Notes complémentaires

Si vous souhaitez exécuter votre routine de copie encore et encore indéfiniment, utilisez une boucle while infinie (while true; do...). Ne faites pas d'appels récursifs (appel du script dans le script ou de la fonction dans la fonction), car cela augmenterait la taille de la pile d'appels et votre script se bloquerait tôt ou tard.

Ce n’est bien sûr qu’un des nombreux moyens d’atteindre le même objectif. Un inconvénient de cette approche est que, chaque fois que l'espace disponible tombe en dessous de 0,5 To ou dépasse 1,0 To, il y aura un appel inutile à enough_space.

Si j'ai mal interprété votre question, merci de me le dire afin que je puisse adapter ma réponse.

2
danzel

Tout d'abord, je vous suggère d'utiliser la commande df pour obtenir l'espace disponible. Vous devez également fournir un chemin système (par exemple /) ou un nom de périphérique (par exemple /dev/sda1) pour simplifier les choses. La sortie de la commande df / exécutée sur mon VPS se présente comme suit:

$ ssh -n user@Host "df /"
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/vda1       25671932 8335064  16009768  35% /

Nous n'avons besoin que de l'espace disponible pour pouvoir filtrer la sortie à l'aide de awk (par exemple):

$ ssh -n user@Host "df /" | awk 'NR > 1 {print $4; exit}'
16009768

Deuxièmement, utilisez les mêmes unités que le résultat de la commande ci-dessus (blocs de 1K) pour la valeur de la variable $LIMIT: 1.5 TB = 1500000000 KB .

Troisièmement, placez la logique principale dans une fonction qui s’appellera de manière récursive encore et encore après la commande sleep. De plus, les lieux de sleep et continue devraient être inversés, je pense :)

Selon ce qui précède, le script pourrait être quelque chose comme ceci:

#!/bin/bash -e

LIMIT='1500000000'

# define the function
main() {
    SIZE="$(ssh -n user@Host "df /" | awk 'NR > 1 {print $4; exit}')"

    if [[ $SIZE -gt $LIMIT ]]
    then 
        echo 'continue'
    else
        echo 'Not enough space.'; sleep 4h
        # call the function
        main
    fi
}

# initial call of the function
main

Selon le @ danzel 's comment au lieu de la récursivité, nous pouvons utiliser une boucle infinie while:

#!/bin/bash -e

LIMIT='1500000000'

while true
do
    SIZE="$(ssh -n user@Host "df /" | awk 'NR > 1 {print $4; exit}')"

    if [[ $SIZE -gt $LIMIT ]]
    then
        # remove the exit command if you do not want to interupt the loop
        echo 'continue'; exit
    else
        echo 'Not enough space.'; sleep 4h
    fi
done
2
pa4080