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 :

ls : valeur de retour si vide


Sujet :

Shell et commandes GNU

  1. #1
    Membre habitué
    Avatar de dj_benz
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 178
    Points : 135
    Points
    135
    Par défaut ls : valeur de retour si vide
    Bonjour,

    Je souhaite faire un script de sauvegarde, d'une arborescence:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Dir
    +-- subdir1
    +-- subdir2
    +-- subdir3
    Les 3 subdir sont connus et figés. Je souhaite sauvegarder leur contenu dans l'équivalent de l'arborescence sur un NAS.

    J'ai donc un code de ce type:
    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
     
    LOG=/mon/log
    DIR=/mon/chemin/dacces/a/Dir
    for f in `ls $DIR`
    do
    	if [ -d "$DIR/$f" ]; then
    		NBFILES=`find $DIR/$f -type f | wc -l`
    		echo "Copie de $DIR/$f..." >> $LOG
     
    		cp -r $DIR/$f/* /mnt/nas/$DIR/$f/
     
    		if [ $? -eq 0 ]; then
    			echo "[ OK ]: $NBFILES fichiers" >> $LOG
    		else
    			echo "[FAIL]: CP command fail" >> $LOG
    		fi
    	fi
    done
    Ce code fonctionne très bien, mais dans mon log, une erreur apparait: "Aucun fichier ou répertoire de ce type" quand un des répertoires "subdir" est vide.

    Comment puis-je palier à cette erreur? Y a-t-il une option à ajouter à cp pour qu'il ignore les vides?

    Merci d'avance.
    Benz
    ______________________________________________________________
    Software is like sex, it's better when it's free - Linus Torvalds

  2. #2
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonsoir.

    Pour commencer, N_Bah le répète très souvent et à juste titre : pas de for i in $(ls) ou parcours dérivés (faire une recherche pour plus de détails).

    Il est préférable d'utiliser le méta-carractère "*" (wildcard) de cette façon (à tester et adapter) :

    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
    LOG=/mon/log
    DIR=/mon/chemin/dacces/a/Dir
    for f in $DIR/*
    do
        if [ -d $f ]; then
            NBFILES=$(find $f -type f | wc -l)
            echo "Copie de $f..." >> $LOG
            cp -r $f/* /mnt/nas/$DIR/
     
            if [ $? -eq 0 ]; then
                echo "[ OK ]: $NBFILES fichiers" >> $LOG
            else
                echo "[FAIL]: CP command fail" >> $LOG
            fi
        fi
    done
    Cordialement,
    Idriss

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 552
    Points : 19 392
    Points
    19 392
    Par défaut
    Bonjour,

    as-tu vraiment besoin d'un fichier log, ou est-ce juste pour voir que ton script ne fonctionne pas correctement ? (s'il fonctionnait correctement enregistrerais-tu un log ?)

    voilà une ligne qui ne générera pas d'erreurs :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find Dir/ -type f -exec cp -t ./ {} \+
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  4. #4
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Attention! On n'utilise jamais 'ls' dans un script! (sinon tu vas fâcher N_BaH )

    Il me paraitrait plus logique d'utiliser une variable 'd' plutôt que 'f' pour désigner un répertoire!

    Sinon, tu peux soit tester la vacuité du répertoire soit, comme tu le fais, le code retour du 'cp'.
    Dans ce dernier cas, comme tu gères l'erreur toi-même, tu n'as pas besoin du message d'erreur fourni par 'cp' sur la stderr, c'est-à-dire que tu peux le mettre à la poubelle:
    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
     
    LOG=/mon/log
    DIR=/mon/chemin/dacces/a/Dir
    SDIR=$(basename "${DIR}")
    for d in $DIR/*
    do
    	if [ -d "$d" ]; then
    		typeset sd=$(basename "${d}") # ou bien sd=${d##*/} # pour les avancés...
    		NBFILES=`$d -type f | wc -l`
    		echo "Copie de $sd dans /mnt/nas/$DIR/$sd..." >> $LOG
     
    		cp -pr "$d"/* "/mnt/nas/$SDIR/$sd/" 2> /dev/null
     
    		if [ $? -eq 0 ]; then
    			echo "[ OK ]: $NBFILES fichiers" >> $LOG
    		else
    			echo "[FAIL]: CP command fail" >> $LOG
    		fi
    	fi
    done
    Attention! si un des répertoires contient un fichier dont le nom commence par '.' il ne sera pas copié.
    Si c'est important, tu peux utiliser cpio ou tar:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (cd "$d" ; tar cf - . ) | (mkdir -p "/mnt/nas/$SDIR/$sd" ; cd "/mnt/nas/$SDIR/$sd" ; tar xf -)

  5. #5
    Membre habitué
    Avatar de dj_benz
    Homme Profil pro
    Inscrit en
    Octobre 2002
    Messages
    178
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Octobre 2002
    Messages : 178
    Points : 135
    Points
    135
    Par défaut
    Merci à tous pour vos réponses.

    Je viens de voir que mon titre est faux: c'est le code retour de CP (et non LS) que je voulais analyser.

    OK N_BaH, je n'utiliserai plus ls. Je ne le savais pas mais je me suis renseigné. Merci.

    Le problème en utilisant la méthode "for d in $DIR/*", est que l'arborescence complète sera dans ma sauvegarde:
    DIR=/mon/chemin/dacces/a/Dir
    sur le NAS, je voudrais uniquement: /mnt/nas/Dir/....

    Je vais donc utiliser:
    cd $DIR
    for d in ./*

    Je souhaite garder les messages d'erreur, mais pas les répertoires vides. Le but de garder mon log est de vérifier en arrivant le matin, que la sauvegarde n'a pas rencontré de problèmes.
    Voilà à quoi j'ai pensé:

    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
    LOG=/mon/log
    DIR=/mon/chemin/dacces/a/Dir
    cd $DIR
    for d in ./*
    do
    	if [ -d "$DIR/$d" ]; then
    		NBFILES=`find $DIR/$d -type f | wc -l`
     
    		if [ $NBFILES -ne 0 ]; then
    			echo "Copie de $DIR/$d..." >> $LOG
     			cp -pr "$DIR/$d/*" "/mnt/nas/Dir/$d/" 2>>$LOG
     
    			if [ $? -eq 0 ]; then
    				echo "[ OK ]: $NBFILES fichiers" >> $LOG
    			else
    				echo "[FAIL]: CP command fail" >> $LOG
    			fi
    		fi
    	fi
    done
    Moi, c'est cd que j'aime pas trop utiliser en scripts...

    Que pensez-vous de cette solution?
    Benz
    ______________________________________________________________
    Software is like sex, it's better when it's free - Linus Torvalds

  6. #6
    Rédacteur

    Avatar de ok.Idriss
    Homme Profil pro
    IS Consultant
    Inscrit en
    Février 2009
    Messages
    5 220
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : IS Consultant
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2009
    Messages : 5 220
    Points : 19 452
    Points
    19 452
    Par défaut
    Bonjour.

    Le ./* est inutile. Dans ce cas autant écrire directement :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for d in *; do
        # ...
    done
    Mais la solution du $DIR/* reste préférable. Tu n'aura pas eu de copie du chemin complet si tu avait fait ton "cp" de cette manière :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    cp -pr $d/* /mnt/nas/Dir/
    ($d est un chemin complet d'où le fait que tu copiait une arborescence complète ).

    Encore inutile :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if [ -d "$DIR/$d" ]; then
    => if [[ -d $d ]]; then.

    Cordialement,
    Idriss

  7. #7
    Rédacteur/Modérateur
    Avatar de Winnt
    Homme Profil pro
    budget et contrôle de gestion
    Inscrit en
    Décembre 2006
    Messages
    1 978
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France

    Informations professionnelles :
    Activité : budget et contrôle de gestion
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 978
    Points : 4 130
    Points
    4 130
    Par défaut
    Bonjour,

    Pourquoi ne pas utiliser rsync ?
    En dehors du fait qu'il est toujours instructif de faire soi même.
    Winnt
    Merci de lire les règles du forum LaTeX et Qu'est ce qu'un ECM ?.
    N'hésitez pas à parcourir la FAQ la réponse y est peut-être déjà.
    Pensez au bouton si votre problème est résolu.


    C'est en Linuxant qu'on devient .... geek
    Et c'est en LateXant qu'on devient flemmard
    Mon blog tout neuf.
    Articles : présentation de la distribution Gentoo, Les index sous LaTeX et leur personnalisation.

  8. #8
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par dj_benz Voir le message
    Le problème en utilisant la méthode "for d in $DIR/*", est que l'arborescence complète sera dans ma sauvegarde:
    DIR=/mon/chemin/dacces/a/Dir
    sur le NAS, je voudrais uniquement: /mnt/nas/Dir/....
    C'est pas faux ! J'ai corrigé le script que j'avais fourni!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 17/01/2008, 15h55
  2. fonction operator, valeur de retour
    Par butch dans le forum C++
    Réponses: 21
    Dernier message: 20/09/2004, 10h30
  3. [VB6] Valeur de retour pour une Form
    Par preverse dans le forum VB 6 et antérieur
    Réponses: 3
    Dernier message: 17/08/2004, 17h16
  4. Valeur de retour d'une procédure externe
    Par elekis dans le forum x86 32-bits / 64-bits
    Réponses: 4
    Dernier message: 16/04/2004, 16h45
  5. Pourquoi une seule valeur de retour pour les fonctions ?
    Par Bruno75 dans le forum Langages de programmation
    Réponses: 33
    Dernier message: 18/01/2004, 13h58

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