Forum Linux.général xargs et caractères spéciaux

Posté par  .
Étiquettes : aucune
0
8
fév.
2008
bonjour,
j'essaye d'exécuter la commande suivante :
"
cat user | xargs -i -t mv /backup_home/backup_old/backup_user_{}* /backup_home/backup_old/{}
"
Ce 'truc' est sensé lire les noms d'utilisateurs dans $user et de déplacer (mv) les fichiers qui contiennent le nom lu vers un répertoire dont le nom est celui du user lu (via les parenthèses {}).
Evidemment, si je poste c'est que cela ne marche pas comme prévu.
Les messages que j'obtiens sont du type suivant :
"
mv /backup_home/backup_old/backup_user_root* /backup_home/backup_old/root
mv: ne peut évaluer `/backup_home/backup_old/backup_user_root*': Aucun fichier ou répertoire de ce type.
"
Evidemment, les fichiers contennant root existent.
Je suppose que le caractère * est considéré comme faisant partie du nom de fichier alors que je veux copier tous les fichiers qui débutent par 'backup_user_root' et l'étoile (*) voulant évidemment dire 'quelque soit les car suivants'.
Bref : avez-vous une solution pour copier via xargs tous les fichiers contenant 'root'?
alei69
  • # euh

    Posté par  . Évalué à 2.

    je ne sais pas avec xarg
    mais avec un
    for i in $( cat user)
    do
    echo mv /backup_home/backup_old/backup_user_${i}* /backup_home/backup_old/${i}
    done

    retirer le echo si ca donne bien ce que tu veux, je me demande si ce n'est pas
    /backup_home/backup_old/backup_user_${i}/* ( avec un / en plus )

    Il ne faut pas décorner les boeufs avant d'avoir semé le vent

  • # ça ne peut pas marcher :(

    Posté par  . Évalué à 1.

    En effet, le matching sur l'* est fait par le shell, pas par xargs... et en pratique, il se passe ceci:

    1) le shell analyse la ligne, et voie la commande suivante:

    xargs -i -t mv [...]/backup_user_{}* /backup[...]

    2) il cherche donc à évaluer, mais comme le [...]_user_{}* ne correspond à rien, il laisse tel quel (note: un tcsh aurait généré une erreur no match)

    3) la commande xargs recoit donc le pattern avec l'*, comme tu t'y attend en fait;

    4) xargs remplace le {}, car tu le lui as demandé...

    5) et il lance lui-même la commande, donc l'* n'est pas évaluée par le/un shell...

    ...d'où problème.

    Je te conseilles donc fortement la solution que te proposes fearan ci-dessus, car dans son cas le shell voie bien l'* après la substitution, puisqu'il la fait lui-même.


    PS1: Perso, plutôt qu'un for, j'utilise un while qui est moins source de problèmes:
    cat user | while read name; do mv ...$name...; done

    PS2: Penses à bien mettre des guillements (") autours des chemins si tu veux éviter les problèmes...
    • [^] # Re: ça ne peut pas marcher :(

      Posté par  . Évalué à 1.

      Merci à tous les deux.
      J'ai donc créé un fichier avec un 'for..do..done': cela fonctionne.
      Je vais essayer avec un 'while'.

      En fait , j'avais ma ligne de commande dans /var/spool/cron/root.
      Je vais devoir créer un exécutable, ce que je voulais ne pas faire pour éviter les oublis lors des changements de versions ou ré installation de Operating System.

      Merci,
      C'est en forgeant qu'on devient forgeron..
      • [^] # Re: ça ne peut pas marcher :(

        Posté par  . Évalué à 1.

        un exe ?

        ben tu peux rendre ton script executable en faisant
        chmod 755 ton_script

        si tu utilises du code au standard posix, tes seuls contraintes seront d'etre sur que xargs soit present

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.