Bonjour à tous, je parcours régulièrement ce forum dans lequel je trouve souvent des réponses mais après avoir passé pas mal de temps sur un enchainement de commandes, je sèche…
Pour info je ne suis ni programmeur ni informaticien, mais passionné d'informatique pour me faciliter la vie.
J'ai des fichiers de sauvegardes horaires très nombreux et je souhaite récupérer assez facilement certaines versions de fichiers à certaines dates et les recopier à un autre endroit pour exploitation. La ligne de commande suivante me convient et fonctionne pour rechercher toutes les versions du fichier "7964.vce" dans mon répertoire de sauvegarde courant "/share/data2/D/" et "recopier" les versions de ce fichier avec arborescence conservée dans mon repertoire d'export "/share/data2_export/7964/".
COMMANDE 1 [/share/data2/D/] /opt/bin/find . -name "7964.vce" -exec rsync -a -R {} /share/data2_export/7964/ \;
Le soucis est que j'ai des milliers de répertoires quotidiens et cette commande prend du temps et je voudrais cibler ma recherche sur novembre 2022 par exemple avec la commande suivante qui fonctionne :
COMMANDE 2 [/share/data2/D/] /opt/bin/find . -type d -name "22_11_*" -maxdepth 1
le résultat retourné est le suivant :
./22_11_01
./22_11_07
./22_11_03
./22_11_02
./22_11_04
./22_11_08
La commande suivante me crée bien un fichier liste.txt dont le contenu est repris ci-après
[/share/data2/D] # /opt/bin/find . -type d -name "22_11_*" -maxdepth 1 -exec /opt/bin/find {} -name "7964.vce" > liste.txt \;
./22_11_07/backup_22_11_07_17h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_07/backup_22_11_07_13h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_07/backup_22_11_07_12h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_03/backup_22_11_03_09h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_03/backup_22_11_03_10h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_02/backup_22_11_02_11h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_02/backup_22_11_02_15h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
./22_11_04/backup_22_11_04_13h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
Ce sont bien ces 8 versions de fichiers de 7964.vce qui doivent être recopiées via rsync.
Je voudrais faire la COMMANDE 1 mais uniquement sur les repertoires commençant par "22_11_*" extraits de la COMMANDE 2.
J'ai essayé avec des pipes, des cat, des xargs, sans succès car je ne suis pas assez calé…
Je voudrais donc que la commande 2+1 suivante fonctionne
COMMANDE 1+2 [/share/data2/D] # /opt/bin/find . -type d -name "22_11_" -maxdepth 1 -exec /opt/bin/find {} -name "7964.vce" \; -exec rsync -a -R {} /share/data2_export/7964/ \;
J'ai bien conscience que le problème vient du {} qui suit la commande rsync mais je n'arrive pas à lui faire relire le résultat de la 2ème commande find…
Merci d'avance aux sachants pour qui le problème est surement basique mais pas pour moi !
# questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 6.
Par curiosité, que te donne ceci ?
Ensuite, pourquoi ne veux-tu pas faire un fichier que lirait
rsync
ensuite ?“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: questions
Posté par Sioncarf59 . Évalué à 2.
Merci Gil pour tes réponses.
J'ai testé et en gros rien ne fonctionne en l'état. Je pense que cela vient de mon "linux".
Je suis sur un NAS Qnap TS 219 installé depuis quelques années déjà mais qui tourne toujours bien pour mes besoins.
Après réflexion, je me souviens qu'il manquait pas mal d'options dans les commandes find par exemple et j'ai du, avec l'aide d'un ami, installer des package IPKG pour obtenir les options complémentaires de find et de Xargs qui ne fonctionnaient pas de base.
Il semblerait que j'ai un linux basic light d'installé et c'est surement pour cela que les options de rsync --files-from= ne fonctionne pas je pense.
C'est la raison pour laquelle je dois chercher la commande find via /opt/bin/find qui a été ajoutée à cet endroit pour pouvoir disposer de toutes les options.
Concernant les options installées, je suis incompétent pour refaire ce que mon ami avait fait à l'époque. Ce que je vois dans /opt/bin/find ce sont les commandes supplémentaires installées par exemple find@ et xargs@ mais je ne vois pas de rsync@ installé, ce pourquoi je ne dispose pas des options un peu poussées mais on s'éloigne du sujet..Je vais me rapprocher de mon ami pour savoir s'il peut m'aider sur ce point d'installation afin que la commande rsync puisse fonctionner avec les options.
[^] # Re: questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 3. Dernière modification le 10 novembre 2022 à 01:18.
Bonjour,
Info importante qu'il manque dans le message initial. :) Ce ne sont pas des distributions GNU/Linux et les systèmes de ces NAS ne prétendent pas être des Linux… En fait ça utilise un noyau Linux et un BusyBox en général.
Du coup, je comprends mieux :
BusyBox ne connait pas l'option
-h
; il faudra utiliser justetime
tout court. C'était pour voir laquelle des deux est plus optimale ; mais il y avait malheureusement une erreur dans ma seconde commande…Pour la première, je crois me souvenir que le filtre
-name
ne prend pas en compte les répertoires dans l'expansion ; raison pour laquelle j'avais voulu bien séparer les parties par/
mais probablement à peaufiner.Pour la seconde, le filtre est
-regexp
sinon ça ne trouvera effectivement pas.“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 1.
Encore une erreur pour la seconde : c'est
-print
et non-ok
qui attend un argument et est similaire à-exec
Pfff, faut que je dorme moi.“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 3.
Oui, les NAS fournissent une CLI vraiment très légère (en général BusyBox) ; mais ce n'est pas lié. La commande, pour ton système, a juste été compilé sans certaines options et il est juste bon de le savoir pour pouvoir adapter.
Dans le cas présent, on comprend mieux pourquoi tu veux enchaîner les deux commandes, et du coup je pense que
xarg
est la bonne piste. Mais pour cela, il vaut mieux terminer la recherche par-print0
(par défaut, quand rien n'est spécifié, on fait un-print
tout court) et non-exec
; et de l'autre côté avoir l'option-0
; brefComme je suppose que tu utilises Bash, tu peux utiliser
type rsync
pour savoir ce que ton shell exécute (il te dira si c'est un alias, ou si c'est une commande laquelle du path il prend —ce qui est utile aussi quand on a plusieurs binaires portant le même nom.)Dans tous les cas, tu peux utiliser
command -v rsync
qui t'indiquera le premier binaire disponible dans ton PATH.Le
@
à la fin des commandes indique juste que ce sont des liens symboliques : je pense que le déballage de BusyBox a été fait dans ce répertoire car/opt/bin
apparait quand tu fais“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: questions
Posté par Sioncarf59 . Évalué à 2.
Merci encore Gil pour tes explications, effectivement je ne suis pas un pro du tout dans ce domaine, je ne connais pas bien la différence entre unix, linux…, je suis un utilisateur windows et MS-DOS à la base, bref un user de base mais je vois bien toute la puissance possible des commandes Linux ou Bash visiblement (je l'ignorais)
La commande
type rsync
me renvoiersync is /usr/bin/rsync
La commande
command -v rsync
me renvoie/usr/bin/rsync
Le déballage de BusyBox a été fait dans ce répertoire
/opt/bin
> réponse oui !Je vais creuser avec les options -print0 et xargs -0.
Un ami m'avait fait des scripts il y a quelques années et il s'était pris la tête avec cette limitation des commandes en Bash donc.
Un extrait de ce script fonctionne ci dessous par exemple
/opt/bin/find /share/data/* -type f -mmin -60 -print0| xargs -0 tar cf - |
[^] # Re: questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2.
Pas de souci. :) C'est vrai que c'est puissant si on prend le temps de s'y consacrer (parce-que ce n'est pas toujours simple.) Même c'était aussi limité que du DOS, le fait d'avoir les redirections et le tube en plus est un vrai plus.
Je viens de penser à un truc : vu que ton
rsync
n'accepte pas l'option--files-from=
; on peut peut-être tricher en faisant une indirection de fichier ? (attention, bash/ksh/zsh etc. mais ça ne fonctionne pas forcément avec tous les shells)“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: questions
Posté par Sioncarf59 . Évalué à 1.
Indirection ? je découvre un mot ! mais d'après ce que j'ai lu ce serait une sorte de numéro (Inode ?) de classement unique à chaque fichier ou dossier.
L'idée étant de se servir de ces inodes pour appliquer la commande Rsync.
j'ai testé la commande suivante
[/share/data2/D] # /opt/bin/find . -maxdepth 1 -type d -name "22_11_*" -exec /opt/bin/find {} -name "7964.vce" -print0 \;| xargs -0 ls -li
qui me retourne bien la liste des mes fichiers avec les inodes en début de ligne :
75932330 -rwxr-x--- 1 francois everyone 274638 Nov 2 08:59 ./22_11_02/backup_22_11_02_09h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
84369674 -rwxr-x--- 1 francois everyone 277122 Nov 2 10:35 ./22_11_02/backup_22_11_02_11h00/share/archives/TBC/Save_VCE_Disque Ext/7964_Saint_André/7964.vce
Visiblement Xargs réinjecte bien les données d'entrées de la commande simple ls mais dès que la commande est un peu plus complexe telle que rsync qui demande une source et une destination, j'ai l'impression que cela ne fonctionne pas.
[^] # Re: questions
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 11 novembre 2022 à 19:24.
Pardon, je voulais parler de redirection d'entrée (de manière indirecte vu que la commande attend plutôt de lire l'entrée standard et non un fichier). Donc, au lieu de
rsync -aR --files-from=liste.txt /share/data2_export/7964/
on aurait :plutôt
rsync -aR $(cat liste.txt) /share/data2_export/7964/
(qui, hélas, à l'heure actuelle ne fonctionnera pas, comme signalé plus loin…) ;ou encore
rsync -aR <liste.txt /share/data2_export/7964/
(qui, hélas, n'est pas accepté par tous les shell ou après des acrobaties avecash
—cf. l'exemple de la boucle plus loin…)Voir option
-I
évoqué plus bas ; ça devrait solutionner plus élégamment le problème.“It is seldom that liberty of any kind is lost all at once.” ― David Hume
# pistes
Posté par benja . Évalué à 2. Dernière modification le 09 novembre 2022 à 21:28.
À vue de nez et en n'étant point sûr que ces solutions soient idéales, je penserais à:
moins précis, utiliser les prédicats
-wholename '*/22_11_*' -type f -name 7964.cve
utiliser rsync uniquement, avec les --exclude/--include voire les filter-rules. C'est clairement possible pour faire la sélection, mais c'est assez compliqué à faire (et je ne suis pas trop motivé pour chercher maintenant, désolé). Par contre il n'est pas possible—il me semble—d'aplatir la hiérarchie en même temps. Donc tu te retrouve avec la même structure, mais qui est expurgée de ce qui ne te convient pas. Pour aplatir, tu peux utiliser un find du côté réception. C'est assez trivial:
find hiearchie -type f -exec mv -T /destination {} +
.*: au risque de dépasser la longueur maximale d'une commande. normalement 200k sous linux, mais vu que c'est un nas il se peut que ce soit un environnement minimaliste avec des limites beaucoup plus strictes.
[^] # Re: pistes
Posté par Sioncarf59 . Évalué à 1.
Merci à toi Benja pour ces très bonnes pistes !
Vu ma réponse précédente, il semble donc que mon langage soit du bash avec des commandes limitées.
et la commande find ci dessous imbriquée avec le
$
ne semble pas fonctionner ni celle avec-wholename
find $(find /share/data/D2 -type d -maxdepth 1 -name 22_11\*)
Pour rappel la commande suivante fonctionne bien mais pour ressortir 8 fichiers d'un total de quelques Mo, cela prend presque 15mn d’où mon besoin de cibler sur certains dossiers (commençant par "22_11_*" dans lesquels rechercher avec
-maxdepth 1
)/opt/bin/find . -name "7964.vce*" -exec rsync -a -R {} /share/data2_export/7964/ \;
la commande rsync fait donc bien ce qui est demandé, c'est juste que je n'arrive pas à lui mettre les données restreintes de 2 commandes find enchainées.
Comme dit avant la piste du print -0 et du xargs -0 devrait marcher.
[^] # Re: pistes
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2.
Bizarre. Qu'as-tu comme message d'erreur ?
Par ailleurs, que te renvoie :
echo $SHELL
?“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: pistes
Posté par Sioncarf59 . Évalué à 1.
Bonjour Gil
echo $SHELL
renvoit/bin/sh
La commande
find $(find /share/data2/D -type d -maxdepth 1 -name 22_11\*) -type f -name 7964.vce
me renvoit le massage ci dessousBusyBox v1.01 (2013.04.25-18:11+0000) multi-call binary
Usage: find [PATH...] [EXPRESSION]
CSearch for files in a directory hierarchy. The default PATH is
the current directory; default EXPRESSION is '-print'`
Pour lui le Path avec $ n'est pas reconnu visiblement.
Entre temps j'ai essayé avec print0 et xargs -0 sans succès, je dois mal m'y prendre ou alors la limitation du bash fait que ca ne marche pas , j'ai essayé la commande suivante et d'autres variantes :
/opt/bin/find . -maxdepth 1 -type d -name "22_11_*" -exec /opt/bin/find {} -name "7964*.vce" -print0 \; | xargs -0 rsync -aR "/share/data2_export/7964/"
j'ai le message de retour suivant :
'ERROR: destination must be a directory when copying more than 1 file
rsync error: errors selecting input/output files, dirs (code 3) at main.c(788) [Receiver=3.0.7]
rsync: connection unexpectedly closed (9 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(601) [sender=3.0.7]'
J'arrive à stocker les résultats de la commande suivante dans un fichier liste.txt dans lequel la liste des fichiers à copier est correcte mais je ne parviens pas via Rsync à ce qu'il reprenne le contenu de cette liste qui pourrait être une solution.
/opt/bin/find . -maxdepth 1 -type d -name "22_11_*" -exec /opt/bin/find {} -name "7964.vce" > liste.txt \;
[^] # Re: pistes
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2. Dernière modification le 11 novembre 2022 à 19:07.
Arf, on (en tout cas moi) a(i) pensé que tu utilisais
bash
, mais c'est visiblement un autre shell limité au vu de ce que tu nous montres.OK, ton shell est un dérivé du
ash
implémenté dans BusyBox.J'aurais pourtant juré qu'il connait la syntaxe
$(…)
; à moins que ce soit parce-que c'est une version pas à jour… (les dernières stables sont 1.34.1 et 1.33.2 de septembre et novembre 2021 et il y a eu beaucoup de corrections deash
depuis la version 1.01…)Une solution un peu crade serait de boucler sur les lignes du fichier
Le souci ici n'est pas au niveau du shell :)
xargs
balance les lignes en argument de la commande …donc les ajoute à la fin, alors que, contrairement àls
et autres commandes simples auxquelles cela correspond,rsync
les veut avant la fin (le dernier argument étant la destination.) Maisxargs
a prévu le coup :C'est toi qui choisi la chaine de marquage (j'ai mis
ICI
) de sorte que ce ne soit pas en conflit avec le reste de la commande, et tu indiques àxargs
par l'option-I
que c'est à l'emplacement de cette chaîne qu'il faut poser les arguments et non à la fin. ;)“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: pistes
Posté par Sioncarf59 . Évalué à 1.
Bonjour Gil, merci encore pour ton aide mais visiblement cela ne fonctionne pas non plus, il semble que l'option -I de xargs ne soit pas disponible, j'ai juste 4 options dispo : -r -x -0 et -t dans mon shell…
Tu as passé un certain temps à m'aider et je t'en remercie vivement ainsi que Benja.
J'opte finalement pour le script et la solution "un peu crade" que tu m'as donnée ci dessous avec un script "un peu crade aussi" je suppose vu mon niveau mais au moins ca marche et ca me suffit !
#!/bin/sh
read -p "entrer repertoire de recherche dans data2/D/ sous forme 'AA_MM_*' :" rep
read -p "entrer repertoire cible a creer dans /data2_export/ 'DOSSIER' :" cible
read -p "entrer nom fichier recherchés 'fichier.ext ou *' :" fich
repcible="/share/data2_export/"ScibleS"/"
echo $repcible
mkdir "$repcible"
/opt/bin/find /share/data2/D/ -maxdepth 1 -type d -name "$rep" -exec /opt/bin/find {} -name "$fich" > "Srepcible"S"liste.txt" \;
resultat="Srepcible"S"liste.txt"
cat $resultat
nb=$(wc -l < $resultat)
echo SnbS" fichiers trouvés"
read -p "Extraire ces fichiers ? appuyer sur 'o' ou 'n' " reponse
if [ "$reponse" = "n" ]; then exit
fi
if [ "$reponse" = "o" ]; then
while IFS= read -r line <&3; do
rsync -aR "$line" "$repcible"
done 3< "Srepcible"S"liste.txt"
fi
NB : j'ai mis des "S" à la place de certains "$" pour ce post sinon c'était illisible
bref un GRAND MERCI A VOUS DEUX !
[^] # Re: pistes
Posté par Gil Cot ✔ (site web personnel, Mastodon) . Évalué à 2.
Je ne m'y attendais pas, vu que
-I
est une option POSIX ; mais bon vu que le BusyBox est vraiment très vieux… Il ne faut pas hésiter à le mettre à jour dès que possible.Heureusement qu'il restait la solution avec la boucle shell.
Pour plusieurs lignes de code, il faut utiliser la syntaxe de bloc de code…
https://linuxfr.org/wiki/aide-edition#toc-code-avec-coloration-syntaxique
…en veillant à sauter une ligne avant et après. Dedans, les dollars n'y sont pas problématiques et on a la coloration syntaxique.
Si ça peut te rassurer, il y en a qui n'en mènent pas plus large au bout de dix ans. Mais voici quelques trucs/astuces pour améliorer la portabilité (i.e. que ça fonctionne le jour où tu changes de shell/machine …sous réserve qu'on ne rencontre pas quelque chose d'encore plus limité) :
repcible="/share/data2_export/"ScibleS"/"
; il faut utiliser directement la chaîne avec la possibilité de remplacement :repcible="/share/data2_export/$cible/"
echo SnbS" fichiers trouvés"
seraitecho "$nb fichiers trouvés"
resultat="Srepcible"S"liste.txt"
il faut utiliser la syntaxe des noms de variable entre accolades : `resultat="${repcible}liste.txt"mkdir "$repcible"
etif [ "$reponse" = "x" ]; then
echo "$repcible"
cat "$resultat"
nb=$(wc -l < "$resultat")
read
accepte l'option-p
car ce n'est pas le cas partout. Donc je prend l'habitude de faire en deux temps… Par contre, sauf bonne raison, il faut toujours utiliser l'option-r
dans les scripts : ça évite les surprises avec certains caractères spéciaux (plus particulièrement les\
qu'il tente d'interpréter)“It is seldom that liberty of any kind is lost all at once.” ― David Hume
[^] # Re: pistes
Posté par Sioncarf59 . Évalué à 1.
Merci Gil pour ces infos précieuses
# précisions et pistes
Posté par steph1978 . Évalué à 2.
avec des spécifications plus précises il serait possible de mieux optimiser.
find -exec
est très lent car il lance un processus par fichier/dossier trouvé.Si tu pouvais te permettre de tout transférer,
rsync -r source/ destination/
serait très rapide. Rsync étant très efficace pour ne transférer que les différences.Tu peux essayer avec un
rsync --include="./22_11_*" ./ destination/
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.