Besoin d'aide script en bash (transfert ssh multific d'un coup)

Fermé
gnugo - 25 juin 2013 à 16:34
Flachy Joe Messages postés 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 - 19 juil. 2013 à 14:38
Bonjour,

Je cherche à faire un script qui va transférer des fichiers (passés en argument) d'un serveur à un autre en utilisant SSH.
Le problème c'est que je voudrais compresser ces fichiers à la volée avant de les transférer mais également les enregistrer compressés sur le serveur de destination.

Petit "schéma" :
Serveur départ --SSH-- Serveur 1 -- SSH -- Serveur 2 -- SSH -- Serveur arrivée
fic1,fic2,... ===================================> fic1.gz,fic2.gz

C'est évidemment faisable par une simple boucle sur la liste des fichiers
Du genre for fic in $*; do cat $fic | gzip | ssh serv1 "ssh serv2 'ssh serv_final cat >$fic.gz'"; done
Mais cette manière de faire est très très lente car elle ouvre 1 tunnel ssh pour chaque fichier
Je souhaite donc les transférer tous en même temps.
Par exemple en faisant une archive, ce serait éventuellement possible : on fait un tar compressé de tous les fichiers que l'on envoie dans le pipe SSH.
Mais en faisant cela, j'obtiens une archive compressée alors que je veux chaque fichier compressé individuellement.
On pourrait très bien extraire l'archive puis tout rezipper... mais ça revient à compresser 2 fois et ça ce n'est absolument pas performant, voire idiot sur le principe.

Auriez-vous une idée à me suggèrer ? Je ne trouve de meilleure façon de faire... sauf à reecrire tout un programme d'archivage qui ferait une archive avec des fichiers compressés individuellement....

Merci d'avance :-D
A voir également:

5 réponses

zipe31 Messages postés 36402 Date d'inscription dimanche 7 novembre 2010 Statut Contributeur Dernière intervention 27 janvier 2021 6 415
25 juin 2013 à 18:17
Salut,

Tu compresses tes fichiers individuellement au départ :
gzip *

Tu crées une archive tar à la volée que tu envoies via ssh et tu la détarres toujours à la volée dans le répertoire de ton choix :
tar zcf - * | ssh user@serveur 'cd /chemin/ ; tar xzf -'

0
Salut,
Le souci c'est justement que je ne peux pas compresser tous les fichiers au départ car cela implique de les enregistrer sur le disque du serveur.
Il me faut impérativement cette compression à la volée d'où mon problème :/
0
SI vous avez une autre idée à me proposer ... :-)
0
dubcek Messages postés 18744 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 4 septembre 2024 5 617
29 juin 2013 à 12:38
hello
les fichiers sont compressés, envoyés dans base64 précédés d'une entête avec le nom, qui permet de recréer le fichier avec awk.
essayer ça:
for F in * ; do echo ++++++++++++ $F.gz ; gzip -c $F | base64 ; done | ssh user@server "cd /dest ; awk '/^+++++++/ {f=$2; next} {print | \"base64 -d > \" f}"
(j'ai pas testé avec ssh, problèmes de " et de ',sûrement)
0
Merci!
Belle solution!
Je vais essayer de l'appliquer
Juste un regret, le base64 qui augmente la taille des données à transférer. J'aimerais bien m'en passer mais je suppose que awk aura du mal à lire du binaire ( et ça deviendrait dangereux car les caractères +++++ ne seraient plus réservés qu'à l'en-tête.
... peut être en donnant nom de fichier + taille en octets pour séparer mais ça me parait impossible vu qu'on ne connait pas la taille avant de zipper le fichier
...Le plus simple serait d'utiliser quelquechose de plus performant que base64 qui nous laisse un caractère non utilisé pour notre en-tête (au pire on pourra utiliser autre chose qu'awk à l'arrivée si la lecture de flux binaire pose problème).
Si vous avez une idée je suis preneur :) )
Encore merci !
0
dubcek Messages postés 18744 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 4 septembre 2024 5 617
Modifié par dubcek le 17/07/2013 à 16:41
base64 encode les fichiers compressés, donc de tailles bien diminuées
on pourrait mettre la taille dans l'entête et utiliser dd pour lire exactement le nombre de bytes
0
Mais l'en-tête est envoyée avant le fichier et on ne peut pas connaitre la taille avant d'avoir zippé tout le fichier (pas question de l'écrire temporairement sur disque ou en mémoire, il doit partir le plus vite possible dans le flux par le pipe) :/

Ta 1ere solution est vraiment bonne je pense, il faudrait juste trouver mieux que ce base64 (idéalement un base255 qui utilise tous les caractères possibles sauf 1, par exemple le '\0', qu'on utilisera pour séparer l'en-tête)
0
dubcek Messages postés 18744 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 4 septembre 2024 5 617
18 juil. 2013 à 09:49
0
dubcek Messages postés 18744 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 4 septembre 2024 5 617
19 juil. 2013 à 13:38
testé avec un fichier binaire (tar) 135 Mb, compressé 53 Mb, base64 72 Mb, b85 67 Mb (mais très long)
0
jisisv Messages postés 3645 Date d'inscription dimanche 18 mars 2001 Statut Modérateur Dernière intervention 15 janvier 2017 934
Modifié par jisisv le 17/07/2013 à 16:22
Inspire-toi de ceci:
johand@osiris: ~/tmp $ (tar -czf - *) | ssh localhost '(mkdir ~/brol; cd ~/brol ; tar -xzf -)'



Gates gave ^H sold you the windows.
GNU gave us the whole house.(Alexandrin)
0
Ça fait une archive compressée et ensuite on est obligé de décompresser l'archive pour ensuite recompresser les fichiers un par un.
C'est pour ça que je n'utilise pas d'archiveur comme tar qui ne permettent pas de faire cela.
Je cherche à obtenir des fichiers compressés individuellement sur le serveur d'arrivée, avec une compression faite une seule fois et sur le serveur de départ, le tout dans un seul flux ssh
Donc à aucun moment je ne suis censé décompresser :)
0
dubcek Messages postés 18744 Date d'inscription lundi 15 janvier 2007 Statut Contributeur Dernière intervention 4 septembre 2024 5 617
17 juil. 2013 à 16:42
les fichiers ne sont plus compressés à l'arrivée
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Flachy Joe Messages postés 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 260
17 juil. 2013 à 19:46
Une idée : installer un serveur de partage sur la destination et "l'entunneler" par ssh. https://www.howtoforge.com/nfs_ssh_tunneling
Tu peux définir directement le point de montage comme destination de la compression et tu t'embêtes pas à créer un pseudo protocole de transfert.
0
Flachy Joe Messages postés 2103 Date d'inscription jeudi 16 septembre 2004 Statut Membre Dernière intervention 21 novembre 2023 260
19 juil. 2013 à 14:38
Avec sshfs il n'y a pas besoin de partage nfs :

sudo apt-get install sshfs
mkdir my_ssh #création du point de montage
sshfs user@server: ./my_ssh/ #montage
find . -maxdepth 1 -type f -print -exec bash -c "gzip -c '{}' > './my_ssh/{}.gz' &" \; #compressions asynchrones
fusermount -u ./my_ssh #démontage
rmdir ./my_ssh


Si tu veux faire transiter tes fichiers par plusieurs serveur, il faut monter le répertoire de destination sur le serveur 2 puis le point de montage du serveur 2 sur le serveur 1 et enfin monter le point de montage du serveur 1 sur le client. Les actions de montage pouvant se faire à travers ssh, tu peux tout mettre en place dans le script lancé sur le client.
0