IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Shell et commandes GNU Discussion :

Besoin d'aide pour script bash : amélioration


Sujet :

Shell et commandes GNU

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 5
    Par défaut Besoin d'aide pour script bash : amélioration
    Bonjour à tous,

    J'ai fait un petit script bash me permettant de déplacer les fichiers d'un répertoire de dépôt (ftp) vers un répertoire de travail. Ce script vérifie que le fichier n'est pas en cours d'envoi et si ce n'est pas le cas, déplace ce fichier.

    Le script fonctionne bien, sauf quand un utilisateur me mets des espaces dans un nom de fichier ou pire me créé un sous-repertoire. Malgré mes avertissement cela arrive encore.

    Quelqu'un aurait une idée pour contourner ce problème ?

    Merci beaucoup !!

    Voici le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # Date
    DATE_JOUR=`date +%y%m%d_%H%M%S` # Date du jour
     
    # Chemin des répertoires
    PATH_INIT="/var/***/depot/" # Répertoire de base
    PATH_DEST="/var/***/recupdepot/" # Répetoire de destination
     
    if [ $(ls ${PATH_INIT}/|wc -l) != 0 ]; then
            for i in $( ls ${PATH_INIT}/* -R )
                    do
                            /usr/sbin/lsof $i
                            if [ $? = "1" ]; then
                                    # Fichier n'est pas utilisé"
                                    cp "$i" "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    chmod 777 "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    chown -R stabo "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    echo "Fichier reçu : ${DATE_JOUR}_$(basename $i)" | mail -s "Nouveau fichier sur DEPOT FTP" xxx@yyy.zzz
                                    rm -f $i
                            fi
            done
    fi

  2. #2
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 196
    Par défaut
    remplace

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    if [ $(ls ${PATH_INIT}/|wc -l) != 0 ]; then
            for i in $( ls ${PATH_INIT}/* -R )
    par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ls -1 ${PATH_INIT}/* | while read i

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 5
    Par défaut
    Merci!
    Ce qui donne donc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # Date
    DATE_JOUR=`date +%y%m%d_%H%M%S` # Date du jour
     
    # Chemin des répertoires
    PATH_INIT="/var/***/depot/" # Répertoire de base
    PATH_DEST="/var/***/recupdepot/" # Répetoire de destination
     
    ls -1 ${PATH_INIT}/* | while read i
            do
                            /usr/sbin/lsof $i
                            if [ $? = "1" ]; then
                                    # Fichier n'est pas utilisé"
                                    cp "$i" "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    chmod 777 "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    chown -R stabo "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
                                    echo "Fichier reçu : ${DATE_JOUR}_$(basename $i)" | mail -s "Nouveau fichier sur DEPOT FTP" xxx@yyy.zzz
                                    rm -f $i
                            fi
            done
    fi
    Mais Je dois aussi retirer la partie en rouge on est d'accord ?

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 196
    Par défaut
    oui pour le if


    par contre ... si ton répertoire PATH_INIT est vide le ls te fera une belle erreur (c'est ce qu'on lui demande de faire) ... si le message te dérange tu peux l'envoyer dans les limbes

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ls -1 ${PATH_INIT}/* 2> /dev/null | while ...

  5. #5
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    Bonjour,

    quand la sortie standard de ls n'est pas un terminal (soit quand il est pipé vers une autre commande, ou redirigée vers un fichier), il affiche son résultat sur une seule colonne.
    mais pourquoi utiliser une commande externe ?
    si ton shell est bash :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    shopt -s nullglob
    for f in ./*
    do echo "$f"
    done
    si tu as besoin de descendre dans les sous-répertoires, avec BASH_4 :
    Code BASH : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    shopt -s nullglob globstar
    for f in ./**/*
    do echo "$f"
    done
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 196
    Par défaut
    Je découvre le shopt ça permet en effet de régler le problème du répertoire vide sans rentrer dans la boucle (le if n'était pas la solution au cas ou le répertoire se vide entre le if et le for)

    +1

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 5
    Par défaut
    Bonjour, merci à tous pour vos réponses !

    Voici donc le script avec vos recommandations :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # Date
    DATE_JOUR=`date +%y%m%d_%H%M%S` # Date du jour
     
    # Chemin des répertoires
    PATH_INIT="/var/***/depot/" # Répertoire de base
    PATH_DEST="/var/***/recupdepot/" # Répetoire de destination
     
    shopt -s nullglob
    for i in ${PATH_INIT}/*
    	do
    		cp "$i" "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
    		chmod 777 "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
    		chown -R stabo "${PATH_DEST}/${DATE_JOUR}_$(basename $i)"
    		echo "Fichier reçu : ${DATE_JOUR}_$(basename $i)" | mail -s "Nouveau fichier sur DEPOT FTP" xxx@yyy.zzz
    		rm -f $i
    	done
    Le script ne fonctionne hélas pas quand il y a un espace dans le nom de fichier

  8. #8
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 196
    Par défaut
    à chaque fois que tu utilises $i pense à rajouter les quotes "$i"

    tu peux aussi éviter d'invoquer basename plus d'une fois en utilisant une variable

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 5
    Par défaut
    Ok merci !

    Pour les problèmes d'espaces c'est réglé.
    Subsiste encore le problème de l'utilisateur qui créé un répertoire, là j'ai encore droit a une belle erreur. Je n'ai pas bash4 et ne peux donc pas utiliser la solution de N_BaH.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # Date
    DATE_JOUR=`date +%y%m%d_%H%M%S` # Date du jour
     
    # Chemin des répertoires
    PATH_INIT="/var/***/depot/" # Répertoire de base
    PATH_DEST="/var/***/recupdepot/" # Répetoire de destination
     
    shopt -s nullglob
    for i in ${PATH_INIT}/*
            do
                    j="$(basename "$i")"
                    cp "$i" "${PATH_DEST}/${DATE_JOUR}_${j}"
                    chmod 777 "${PATH_DEST}/${DATE_JOUR}_${j}"
                    chown -R stabo "${PATH_DEST}/${DATE_JOUR}_${j}"
                    echo "Fichier reçu : ${DATE_JOUR}_${j}" | mail -s "Nouveau fichier sur DEPOT FTP" xxx@yyy.zzz
                    rm -f "$i"
            done

  10. #10
    Membre très actif
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    196
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2009
    Messages : 196
    Par défaut
    sinon tu peux aussi essayer le find (qui remplace le for) en créant une fonction

    cela me semble plus clair personnellement :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    function envoiFichier {
      i=$1
      j=$(basename ...
      ...
    }
     
    ....
     
    find ${PATH_INIT} -name "*" -type f -exec   envoiFicher {} \;

    et si tu ne veux pas de fonction

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    find ${PATH_INIT} -name "*" -type f | while read i
    do
         j=$(basename ...
        ...
    done


    sinon tu peux essayer la syntaxe proposée par Nbha

    il te faut y rajouter un
    pour ne garder que les fichiers et exclure les répertoires

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
     
    shopt -s nullglob globstar
    for i in ./**/*
    do 
        if test -f "$i"
        then
             j= ... 
             ....
        fi
    done
    sinon ...

  11. #11
    Modérateur
    Avatar de N_BaH
    Profil pro
    Inscrit en
    Février 2008
    Messages
    7 635
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2008
    Messages : 7 635
    Par défaut
    PATH_INIT="/var/***/depot/" # Répertoire de base
    Tiens ? pourquoi trois astérisques ? pourquoi pas quatre ?
    un seul astérisque suffit, il remplace zéro, un, ou plusieurs caractères.

    basename n'est pas indispensable : j="${f##*/}".

    Pour ce qui est de descendre dans les sous-répertoires sans BASH4, il va falloir utiliser une fonction récursive, qui s'appellera si le fichier est en fait un répertoire, ou qui traitera le fichier si c'est bien un fichier.

    les noms de variables entièrement en majuscules sont, par convention, réservés aux variables environnementale (PATH, PWD...)
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  12. #12
    Futur Membre du Club
    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Mai 2012
    Messages : 5
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    Tiens ? pourquoi trois astérisques ? pourquoi pas quatre ?
    un seul astérisque suffit, il remplace zéro, un, ou plusieurs caractères.
    En fait c'était pas mettre le chemin complet sur le forum, tout simplement.

    Je vais essayer de m'en sortir avec vos commentaires et je reviendrais vers vous...

    En attendant merci à tous !

Discussions similaires

  1. [MySQL] besoin d'aide pour script statistique
    Par samspitz dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 17/10/2008, 16h32
  2. Besoin d'aide pour script en shell pour un novice
    Par king_neo2001 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 01/06/2007, 16h18
  3. [mIRC] besoin d'aide pour scripting
    Par emile13 dans le forum IRC / mIRC
    Réponses: 5
    Dernier message: 03/03/2007, 00h05
  4. besoin d'aide pour script DOS
    Par isaglada dans le forum Windows
    Réponses: 4
    Dernier message: 15/02/2007, 11h07
  5. Aide pour script bash
    Par cmoiki dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 05/01/2007, 23h50

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo