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

Linux Discussion :

[SHELL] - Encapsuler les fonctions de copie


Sujet :

Linux

  1. #1
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut [SHELL] - Encapsuler les fonctions de copie
    Bonjour,

    voila je fias des script qui copie des fichiers pas compliquer
    juste de cp et mv.

    la ou je sais pas faire c'est comment savoir que le cp c'est bien passé ?
    est ce qu'il est possible de faire remonté les erreurs de copie ?
    dans le script bash ?

    ou le dossier source nom trouvé ou desitination n'existe pas ?
    ou la connexion réseau asaué et donc le fichier à mal été copié ?

    comment faire ça svp ?
    merci.

  2. #2
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mika2008 Voir le message
    Bonjour,

    voila je fias des script qui copie des fichiers pas compliquer
    juste de cp et mv.

    la ou je sais pas faire c'est comment savoir que le cp c'est bien passé ?
    est ce qu'il est possible de faire remonté les erreurs de copie ?
    dans le script bash ?

    ou le dossier source nom trouvé ou desitination n'existe pas ?
    ou la connexion réseau asaué et donc le fichier à mal été copié ?

    comment faire ça svp ?
    merci.
    Salut

    Serait utile que tu lises un ou deux tutos shell. Tu peux trouver le mien ici

    Toute commande Unix renvoie toujours un état. Cet état (un chiffre compris entre 0 et 255) est récupéré dans la variable $?.
    Conventionnellement, un état à 0 indique "le programme s'est bien exécuté" et un état différent de 0 indique "le programme a foiré"

    Exemple
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ls -l
    echo $?    => 0   # Le "ls" a réussi
     
    rm -f /etc/passwd 2>/dev/null     # j'espère que tu ne bosses pas sous root
    echo $?    => 1   # Le "rm" a foiré

    Donc en vérifiant la valeur de $? tu peux savoir si ton programme a réussi ou foiré... => if test $? -eq 0

    Accessoirement, l'alternative if du shell possède la possibilité inégalée dans les autres langages de pouvoir checker directement tout programme quel qu'il soit (d'ailleurs quand tu appelles "if test" tu fais un check du programme nommé "test" qui se trouve dans /bin au même titre que les autres)

    Et donc tu peux directement checker un programme pour vérifier qu'il s'est bien exécuté

    Exemple
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if rm -f /etc/passwd
    then
        echo "L'effacement a réussi => dommage"
    else
        echo "L'effacement a raté (ouf)"
    fi

    PS: j'ai parlé de convention pour le status à 0 car rien n'oblige à la respecter. On trouvera par exemple le programme "expr" qui effectue un travail et qui affiche son résultat et qui renvoie un état à
    0 si le résultat affiché n'est pas 0
    1 si le résultat affiché est 0
    2 si expr a foiré

    Et donc si on écrit par exemple ce genre de code
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if expr 1 - 1
    then
        echo "expr a réussi"
    else
        echo "expr a foiré"
    fi

  3. #3
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut
    merci pour
    c'est explication !!!!
    c'est énorme, merci je vais me plonger dans tes explications pour améliorer mon code.

    une dernier chose,

    je vais rajouter des test sur le fonction de copy, mais la j'ai eu vraiment un truc byzarre mon script c'est bloqué sur une copy et n'avancé plus :'(
    impossible de faire un kill de la fonction de copy, j'ai du redemarré le serveur, je ne sais pas c'est du a quoi.
    c'était pourtant une simple copie de fichier, mais elle est resté figé, pourtant quand j'allais voir le fichier il étais bien copié, mais la fonction étais bloqué.

    pour voire que la fonction étais bloqué je faisais un htop et je voyais la foncton de "cp qui étais présente pendant plus de 20 min"

    en fais dans mon script je fais des copies de plusieur fichier donc je l'est numérote et j'écrit le résultat au fur et a muser dans un fichier de log, que je regarde avec la fonction tail -f
    et la il étais bloqué sur le 11 ieme fichier et voulais plus avancé :'(

    il y a peut étre un moyen de timé le programme
    bon je vais voir ton cours merci à toi !!!

  4. #4
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mika2008 Voir le message
    je vais rajouter des test sur le fonction de copy, mais la j'ai eu vraiment un truc byzarre mon script c'est bloqué sur une copy et n'avancé plus :'(
    impossible de faire un kill de la fonction de copy, j'ai du redemarré le serveur, je ne sais pas c'est du a quoi.
    c'était pourtant une simple copie de fichier, mais elle est resté figé, pourtant quand j'allais voir le fichier il étais bien copié, mais la fonction étais bloqué.

    pour voire que la fonction étais bloqué je faisais un htop et je voyais la foncton de "cp qui étais présente pendant plus de 20 min"

    en fais dans mon script je fais des copies de plusieur fichier donc je l'est numérote et j'écrit le résultat au fur et a muser dans un fichier de log, que je regarde avec la fonction tail -f
    et la il étais bloqué sur le 11 ieme fichier et voulais plus avancé :'(
    Je pense que le 11° fichier est un pipe (type "p")

    Un pipe est un outil de communication et de synchronisation inter processus. Un processus écrit un truc dans le pipe et l'autre va lire le pipe et récupère ce que le premier a lu.

    Mais comme c'est aussi un outil de synchro, le noyau Unix bloque le processus qui lit (ou qui écrit) tant qu'un autre processus n'est pas venu écrire (ou lire).

    Exemple: tu ouvres 2 fenêtres terminal
    Dans la première, tu tapes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    mknod toto p
    date >toto
    Là, ça se bloque.

    Dans la seconde, tu tapes Et tu récupères la date et ça débloque la première fenêtre. Et si tu commences par lire toto, alors ça bloquera jusqu'à ce que, ailleurs, tu ailles écrire dans toto.

    Ce principe est super pratique. Par exemple, dans un environnement multi-utilisateurs avec une imprimante, si tout le monde envoie ses fichiers directement sur l'imprimante tout se mélange à l'impression.
    Ben au lieu de développer un outil compliqué de gestion d'imprimante, tu crées juste 2 programmes
    - un programme que t'appelles quand tu veux imprimer et qui envoie ton fichier dans un pipe
    - un programme qui lit le pipe et qui envoie ce qui s'y trouve dans l'imprimante et qui tourne en tâche de fond.
    Et c'est réglé. C'est d'ailleurs ce qui existe déjà

    Donc ta fonction de copie tombe sur ce 11° fichier, cherche à le lire et se retrouve bloquée (puisque personne n'est là pour écrire dedans)
    Te suffit de faire un if test -p <le_fichier> pour gérer le cas. Accessoirement, tu devrais aussi penser à ce qui se passera si elle tombe sur
    - un répertoire => test -d <le_fichier>
    - un lien symbolique => test -L <le_fichier>
    - un fichier spécial bloc ou caractère => test -b <le_fichier> -o -c <le_fichier>
    - un fichier socket => test -s <le_fichier>

    Accessoirement, tu es en train de t'amuser en shell pour découvrir Unix et ses principes et c'est très bien. Mais je ne pense pas que tu aies vraiment besoin de ce programme d'encapsulation. Quand on fait une copie, ça marche. Et si ça ne marche pas, tu le vois de suite. Et si tu fais une copie dans un script, ben te suffit de vérifier $? pour que le script sache si la copie a fonctionné ou pas. Et si tu veux copier complètement un dossier (avec tous ses autres sous-dossiers etc), ben t'as aussi des outils qui, bien qu'ils n'aient pas été fait pour ça, peuvent servir à ça...

  5. #5
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut
    merci trops bon !

    j'étudie ça !!!

  6. #6
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut
    Salut,
    j'ai produit un code, assez long pour un vingtaine de fichier, et le code est presque inbuvable :'(

    un extrait que j'utilise pour chaque fichier à récupérer :
    et j'ai toujours le plantage au moment de la copie. le programme s'arrette et impossible de le relancer ou de le stopper avec htop ou un kill :'(


    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
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
     
    #---------------------------------------------FILES15=*NOM_FICHIER*	#Description fichier-----------------------------------------------------
    DOSSIER_SOURCE=$DOSSIER_1;
    DOSSIER_DESTINATION=$DOSSIER_2;
    FILES=$FILES15;
    MESSAGE=$MESSAGE15;
    #compte le nombre de fichier :
    nbFindFiles=$(ls  $DOSSIER_SOURCE/$FILES | wc -l) 
    echo "nbFindFiles15 = " $nbFindFiles
     
    #Si on a des fichiers
    if (( $nbFindFiles > 0));
    then
    #tableau avec les noms de fichier
    table=( $(ls $DOSSIER_SOURCE/$FILES |  cut -d"/" -f10) )
    	i=$nbFindFiles ; 
    	MESSAGE="$MESSAGE (Nbr fichier = $nbFindFiles) <ul>"
    	for filename in $(ls $DOSSIER_SOURCE/$FILES |  cut -d"/" -f10) ;
    	do 
    		if (( $i > 1));
    		then
    			MESSAGE="$MESSAGE <li><strong>$filename</strong> </li>";
    		else
    			MESSAGE="$MESSAGE <li><strong>$filename</strong> </li>";
    		fi
    		i=$i+1 ;  
    	done
    	MESSAGE="$MESSAGE </ul>";
     
     
     
    	if 	cp $DOSSIER_SOURCE/$FILES $DOSSIER_DESTINATION;
    		then
    			MESSAGE_DEBUG="$MESSAGE_DEBUG  <li><strong> $DOSSIER_DESTINATION;/$FILES  : Copie réussi</strong> </li>";
    			echo "La copie dans $DOSSIER_PREST_EDT_PDF a reussi"
    		else
    			MESSAGE_DEBUG="$MESSAGE_DEBUG  <li><strong>$DOSSIER_DESTINATION;/$FILES  : Copie échoué </strong> </li>";
    				echo "La copie dans DOSSIER_DATALIS_RLV_TIERS à échoué"
    	fi
    	if 	rm $DOSSIER_SOURCE/$FILES;
    		then
    			MESSAGE_DEBUG="$MESSAGE_DEBUG  <li><strong>$DOSSIER_SOURCE/$FILES L'effacement a réussi</strong> </li>";
    			echo "L'effacement a réussi"
    		else
    			MESSAGE_DEBUG="$MESSAGE_DEBUG  <li><strong>$DOSSIER_SOURCE/$FILES L'effacement a échoué</strong> </li>";
    			echo "L'effacement a échoué"
    	fi
     
     
    else 
    MESSAGE="$MESSAGE <strong>Fichier non présent</strong>  </li>";
    fi
    MESSAGE15=$MESSAGE;
    #---------------------------------------------End -FILES15=*NOM_FICHIER*	#Description fichier- ---------------------------------------------
    pour décrire le code, il donne au final deux fichier HTML.
    Un ou tout les donnée son stocker dans $MESSAGE (et qui seras envoyé au utilisateur) et un $MESSAGE_DEBUG à l'admin afin de savoir si les copies et effacement de fichier ce sont bien déroulé.

    le but de ce code est de donnée le nom du fichier qui seras envoyé dans un mail et de déplacer un fichier d'un dossier à l'autre





    je me suis dit que tu pourrais me donnée des idées pour l'améliorer ?
    et me faire des critiques ?

    merci d'avance.

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mika2008 Voir le message
    je me suis dit que tu pourrais me donnée des idées pour l'améliorer ?
    et me faire des critiques ?

    merci d'avance.
    Mouais. Déjà, je m'explique mal ce ls $DOSSIER_SOURCE/$FILES | cut -d"/" -f10. Tu as donc un chemin avec 10 niveaux en profondeur ??? Et que se passera-t-il si tu déplaces le chemin et que ton arbo passe à 12 niveaux ? C'est inmaintenable. Pourquoi ne pas utiliser basename ???

    Essaye aussi de nommer tes variables en minuscule. Tu peux mettre des majuscules pour marquer les mots (style nbDeCaractères) mais une grande difficulté à relire ton code c'est ces noms en full majuscule.

    Et pour ton pb de blocage, rien ne vaut le echo. Affiche donc le nom du fichier juste avant de faire le cp...

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 596
    Points : 19 481
    Points
    19 481
    Par défaut
    un blocage ?
    :
    set -vx
    !

    ...
    je persiste, il ne faut pas utiliser ls dans des scripts

    et il faut limiter au strict nécessaire l'usage de commandes externes

    l'indentation est une bonne habitude à adapter selon le langage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if [ quoi qoi ]
    then
       echo quoi
    else
       echo failed
    fi
    mais oublie les tabulations ! (2,3,4 espaces vont bien)

  9. #9
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par N_BaH Voir le message
    et il faut limiter au strict nécessaire l'usage de commandes externes
    Ah ? Pourquoi ? Je professe justement le contraire argumentant que le shell est très limité justement parce qu'il peut appeler et récupérer l'affichage (le résultat donc) de n'importe quel programme. Et que les programmes externes, compilés, sont bien plus rapides que ce que le shell ferait si on programmait la même chose en shell pur...

    Citation Envoyé par N_BaH Voir le message
    mais oublie les tabulations ! (2,3,4 espaces vont bien)
    :set ts=4 (sous vi)...

  10. #10
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut
    Bonjour
    et merci de vos réponse

    par contre qu'appelle tu "basename" ?

    j'ai pas compris :
    un blocage ?
    :
    set -vx
    !
    ?

  11. #11
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 739
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 739
    Points : 31 068
    Points
    31 068
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Mika2008 Voir le message
    Bonjour
    et merci de vos réponse

    par contre qu'appelle tu "basename" ?
    basename est une commande Unix qui donne le nom de base d'un fichier (le nom sans son arborescence)
    basename /var/spool/log/crontab => crontab

    Il y a aussi son opposé, la commande dirname

    Citation Envoyé par Mika2008 Voir le message
    j'ai pas compris : set -vx ?
    La commande set -x (debug) que tu peux positionner dans ton script où tu veux fera en sorte que ton script affiche tout ce qu'il fait avant de le faire.
    Tu peux demander ensuite d'arrêter avec set +x ce qui te permet de définir une zone particulière de ton algo où tout ce qui se passe sera écrit.
    Attention, ça renvoie énormément d'infos.

    La commande set -v fait presque la même chose. L'une affiche la commande avant expansion (si l'instruction contient une variable ça affiche le nom de la variable) et l'autre après expansion (ça affiche le contenu de la variable)

  12. #12
    Membre régulier Avatar de Mika2008
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    176
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 176
    Points : 71
    Points
    71
    Par défaut
    Bonjour,

    merci Sve@r

    il faut que je reprenne mon code de fond en comble, car comme tu dit il est pas maintenable, il mélange du bach et du PHP?

    :'(

    et la je commence à avoir beaucoup trops de fichier; et a me mélanger les pinceaux.

    Faut que je réfliche à une nouvelle façon d'implémentar ça.

Discussions similaires

  1. Réponses: 31
    Dernier message: 30/03/2006, 17h57
  2. doc sur les fonctions
    Par masterfab dans le forum C
    Réponses: 18
    Dernier message: 23/06/2005, 18h55
  3. Réponses: 11
    Dernier message: 22/12/2003, 22h06
  4. [Postgresql]Problème avec les fonctions ...
    Par fet dans le forum Requêtes
    Réponses: 4
    Dernier message: 02/10/2003, 10h04
  5. Réponses: 7
    Dernier message: 24/05/2003, 16h56

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