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 POSIX Discussion :

Fichier en cours d'utilisation


Sujet :

Shell et commandes POSIX

  1. #1
    Candidat au Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Points : 2
    Points
    2
    Par défaut Fichier en cours d'utilisation
    Bonjour à tous,

    Je suis nouveau sur le forum. Je connais le shell mais vraiment pas un expert.

    Je vous remercie d'avance pour votre aide.

    Voilà mon script :


    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
    #!/bin/ksh
    set -x
    #positionnement des variables
    # récuperation une liste de fichier dans NOM_FIC, et non un seul fichier
    # tant qu'il n'y a pas de fichier, on boucle
     
    while true
     
    do
     
    REP="/home/1000/test"
     
     
    if [ `ls -ltr $REP/* | wc -l` = "0" ]
     
     
        then
          echo "Le repertoire $REP est vide" >> /home/1000/repertoire_vide.log
           else
              for file in `ls -a $REP/*` # ls -1l pour mettre sur une colonne si +sieurs fichiers
    do
                 fuser $file 2> /dev/null
                      if [ $? -eq 0 ] # fuser trouve un process associé dans $file alors on passe au fichier suivant.
                     then
                           sleep  10
     
                                     continue
     
     
    else # fuser trouve pas de process, donc fichier libre on envoi
     
     
    mv /home/1000/test/* /home/1000
     
    fi
    done
    fi
    done


    ----> ce script marche pour 1 seul fichier ou plusieurs mais pas en cours d'utilisation.
    S'il y a 1 fichier "fermé" et 1 en cours d'utilisation, il "move" quand même.

    Avec le fuser, pourtant, je teste le code retour... et il attend que tous les fichiers sont fermés et ne bougent plus.. pourtant, cela ne marche pas.


    Merci encore pour votre aide


    Jacques

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

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

    tous les processus ne gardent pas les fichiers ouverts, mais travaillent sur une copie (sur disque, ou en mémoire), par exemple vim, mais pas less.

    à part ça :
    ON N'UTILISE PAS ls DANS UN SCRIPT !!! on utilise les globs.
    et on ne boucle pas avec for sur la sortie d'une commande !

    puisque tu utlises ksh, tu peux mettre la liste des fichiers (obtenue avec les globs, que, d'ailleurs, tu utilises déjà, comme M. Jourdain, la prose) dans un tableau, qui pourra retourner le nombre exact d'éléments, et non comme wc -l le nombre de lignes.
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  3. #3
    Candidat au Club
    Homme Profil pro
    Technicien réseau
    Inscrit en
    Septembre 2015
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Technicien réseau
    Secteur : Industrie

    Informations forums :
    Inscription : Septembre 2015
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Merci pour ta réponse et excuse moi de te répondre que maintenant (petits soucis...).

    Bon, je crois comprendre que mon script n'est en rien esthétique et que visiblement, la commande fuser lié à un process n'est pas l'idéal et que cela ne marchera pas avec cette commande.

    Je ne comprends pas tout quand tu parles de "globs". Si ce sont des motifs génériques comme l'étoile "*", je l'utilise.

    Je n'ai pas trop d'idées. L'algorithme est simple, limpide mais alors la pratique. Je suis au boulot entouré de gens qui ont des notions de scripting mais pas plus que cela.

    N_Bah, pourrais tu encore m'aiguiller s'il te plait ?

    Il faut bien que je boucle à un moment donné ??

    Est ce que mettre par exemple la sortie d'une commande listant les fichiers dans un fichier texte et ensuite faire une boucle avec le mv aurait plus judicieux ??

    Je nage ^^

    Merci encore de ton aide et de votre aide

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

    Informations forums :
    Inscription : Février 2008
    Messages : 7 538
    Points : 19 360
    Points
    19 360
    Par défaut
    Il faut bien que je boucle à un moment donné ??
    oui, mais directement sur les globs (moitifs génériques, en effet), pas sur la sortie de ls :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in ./*; do echo "$f"; done
    voici qui boucle sur les fichiers du répertoire courant.
    l'emploi d'un fichier temporaire est inutile.

    par contre, désolé, je ne connais pas de solution à ta problématique
    quelqu'un d'autre, peut-être...

    [edit]
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for f in $rep/*; do lsof | grep "${f##*/}"; done
    ???
    .
    N'oubliez pas de consulter les cours shell, la FAQ, et les pages man.

  5. #5
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par jackorde Voir le message
    ----> ce script marche pour 1 seul fichier ou plusieurs mais pas en cours d'utilisation.
    S'il y a 1 fichier "fermé" et 1 en cours d'utilisation, il "move" quand même.
    je comprends pas bien, quel est le comportement attendu du script exactement ? de cette description découle la façon de structurer ton code, l'algorithme
    en l'occurrence ton script actuel est tourné de telle sorte que si un fichier est utilisé le script attend 10s et... passe au fichier suivant, ce qui n'est probablement pas ce que tu veux

    par ailleurs tu précises les options -ltr pour ls, est-ce qu'elles ont leur importance ? (les fichiers doivent-ils être déplacés dans un ordre précis selon leur horodatage ?)

    je me risque à supposer : tu veux déplacer tous les fichiers du répertoire $REP dès qu'ils ne sont plus utilisés, et ce jusqu'au dernier
    dans ce sens je te propose ce bout de 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
    22
    23
    24
    25
    26
    27
    #!/bin/bash
     
    REP="source"
    DEST="destination"
    LOG="log"
     
    echo "=== DEBUT DU SCRIPT ($(date +'%d/%m/%Y à %H:%M:%S')) ===" | tee -a "${LOG}"
     
    liste=(${REP}/*)        # on crée la liste des fichiers à traiter
    nb=${#liste[@]}         # nombre de fichiers dans la liste
     
    while [ $nb -ne 0 ]; do
       for (( index=0; index < $nb; index++ )); do
          fichier=$(readlink -f "${liste[index]}")
          fuser "${fichier}" &>/dev/null && echo "$(date +'%H:%M:%S') ${liste[index]}: en cours d'utilisation" || {
             mv "${fichier}" "${DEST}/" &&
             echo "$(date +'%H:%M:%S') ${liste[index]}: déplacé" &&
             unset liste[$index]
          }
       done
       liste=("${liste[@]}")   # on recrée/met à jour la liste
       nb=${#liste[@]}         # et son nombre d'éléments (pour le while)
       echo "--- reste ${nb} fichier(s) à traiter ---"
       sleep 5 # facultatif, histoire de pas écrouler la machine/les IO, et d'avoir un log pas trop long non plus
    done | tee -a "${LOG}"
     
    echo "=== FIN DU SCRIPT ($(date +'%d/%m/%Y à %H:%M:%S')) ===" | tee -a "${LOG}"
    • le principe est simple, on tient à jour la liste des fichiers à traiter, tant que (while) le nombre de fichier n'est pas tombé à zéro, on continue de travailler, en prenant soin de retirer de la liste (unset) ceux que l'on est parvenu à déplacer
    • on utilise readlink -f pour récupérer le nom complet du fichier (pratique y compris pour les liens symboliques par exemple, et pas d'erreur possible sur le fichier concerné)
    • on utilise une tournure de la forme fuser && PAS OK || OK qui évite de passer par un if explicite sur $? (mais ça revient au même), le "OK" comprenant plusieurs commandes on les met simplement dans un bloc entre accolades
    • à la fin, avant de boucler sur le while, on met à jour la liste (comme on a peut-être retiré des fichiers entre temps) et par conséquent le nombre de fichiers à traiter restant dans la foulée


    on a donc au départ l'arbrescence de test suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    .
    +-- destination/
    +-- pouet.sh
    +-- source/
        +-- fichier1
        +-- fichier 2
        +-- fichier3
        +-- repertoire1/
        +-- repertoire 2/
    et l'exécution du script :
    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
    $ ./pouet.sh 
    === DEBUT DU SCRIPT (24/09/2015 à 10:51:40) ===
    10:51:40 source/fichier1: en cours d'utilisation
    10:51:41 source/fichier 2: en cours d'utilisation
    10:51:41 source/fichier3: déplacé
    10:51:41 source/repertoire1: en cours d'utilisation
    10:51:41 source/repertoire 2: déplacé
    --- reste 3 fichier(s) à traiter ---
    10:51:46 source/fichier1: en cours d'utilisation
    10:51:46 source/fichier 2: déplacé
    10:51:46 source/repertoire1: en cours d'utilisation
    --- reste 2 fichier(s) à traiter ---
    10:51:51 source/fichier1: déplacé
    10:51:51 source/repertoire1: en cours d'utilisation
    --- reste 1 fichier(s) à traiter ---
    10:51:56 source/repertoire1: en cours d'utilisation
    --- reste 1 fichier(s) à traiter ---
    10:52:01 source/repertoire1: déplacé
    --- reste 0 fichier(s) à traiter ---
    === FIN DU SCRIPT (24/09/2015 à 10:52:06) ===
    le fichier de log est créé, on remplacera au besoin tee -a par une simple redirection d'ajout >> si on ne veut pas d'output direct sur le terminal

  6. #6
    Expert éminent sénior
    Avatar de Escapetiger
    Homme Profil pro
    Administrateur système Unix - Linux
    Inscrit en
    Juillet 2012
    Messages
    1 465
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Administrateur système Unix - Linux

    Informations forums :
    Inscription : Juillet 2012
    Messages : 1 465
    Points : 10 994
    Points
    10 994
    Par défaut
    @BufferBob
    Merci pour la commande readlink qui m'était inconnue à ce jour
    « Developpez.com est un groupe international de bénévoles dont la motivation est l'entraide au sens large » (incl. forums developpez.net)
    Club des professionnels en informatique

Discussions similaires

  1. Samba / fichier en cours d'utilisation
    Par dycobe dans le forum Réseau
    Réponses: 2
    Dernier message: 05/03/2008, 10h19
  2. [D7] Lire un fichier en cours d'utilisation
    Par bibi26 dans le forum Delphi
    Réponses: 3
    Dernier message: 05/07/2007, 11h00
  3. [DOM] Fichier en cours d'utilisation - Suppression impossible
    Par schniouf dans le forum Format d'échange (XML, JSON...)
    Réponses: 2
    Dernier message: 15/12/2006, 14h58
  4. Fichier en cours d'utilisation
    Par kendras dans le forum C
    Réponses: 9
    Dernier message: 29/11/2006, 12h45
  5. [VB.NET] Comment acceder au fichier en cours d'utilisation ?
    Par Aspic dans le forum Windows Forms
    Réponses: 1
    Dernier message: 18/02/2006, 17h40

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