Question

J'ai créé un programme qui itère sur un tas de fichiers et invoque pour certains d'entre eux:

scp <file> user@host:<remotefile>

Cependant, dans mon cas, il peut y avoir des milliers de petits fichiers qui doivent transférer et scp est l'ouverture d'une nouvelle connexion ssh pour chacun d'eux, qui a tout à fait certains frais généraux.

Je me demandais s'il n'y a pas de solution où je garde un fonctionnement de processus qui maintient la connexion et je peux l'envoyer « demandes » à copier sur un seul fichier.

Idéalement, je suis à la recherche d'une combinaison de certains programmes d'émetteur et le récepteur, de sorte que je peux commencer un processus unique (1) au début:

ssh user@host receiverprogram

Et pour chaque fichier, j'invoque une commande (2):

senderprogram <file> <remotefile>

et le tuyau de la sortie (2) à l'entrée (1), et cela causerait le fichier à transférer. En fin de compte, je peux envoyer procédé (1) un certain signal fin.

De préférence, le programmes émetteur et récepteur sont des programmes C open source pour Unix. Ils peuvent communiquer à l'aide d'une prise à la place d'un tuyau ou toute autre solution de création.

Cependant, il est une contrainte important que chaque fichier est transféré au moment où j'itérer dessus: il n'est pas acceptable de recueillir une liste de fichiers, puis invoquer une instance de à scp transférer tous les fichiers à la fois à la fin. Aussi, j'ai seulement simple accès shell à l'hôte de réception.

Mise à jour: J'ai trouvé une solution pour le problème de la connexion en utilisant en tête les caractéristiques de multiplexage de ssh, voir ma réponse ci-dessous. Et pourtant, je commence une prime parce que je suis curieux de savoir s'il existe un programme émetteur / récepteur que je décris ici. Il semble qu'il devrait exister quelque chose qui peut être utilisé, par exemple xmodem / ymodem / zmodem?

Était-ce utile?

La solution

De cette façon fonctionnerait, et pour d'autres choses, cette approche générale est plus ou moins droite.

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud

Autres conseils

J'ai trouvé une solution sous un autre angle. Depuis la version 3.9 , supports OpenSSH multiplexage Session : une seule connexion peut effectuer plusieurs sessions de connexion ou de transfert de fichiers. Cela permet d'éviter le coût d'installation par connexion.

Dans le cas de la question, je peut d'abord établir une connexion avec établit un maître de commande (-M) avec une douille (-S) dans un emplacement spécifique. Je ne ai pas besoin d'une session (-N).

ssh user@host -M -S /tmp/%r@%h:%p -N

Ensuite, je peux invoquer pour chaque fichier scp et des instructions pour utiliser le même socket:

scp -o 'ControlPath /tmp/%r@%h:%p' <file> user@host:<remotefile>

Cette commande commence à copier presque instantanément!

Vous pouvez également utiliser la prise de contrôle pour les connexions ssh normales, qui sera ensuite ouvrir immédiatement:

ssh user@host -S /tmp/%r@%h:%p

Si la prise de commande est plus disponible (par exemple parce que vous avez tué le maître), ce revient à une connexion normale. Plus d'informations sont disponibles dans cet article .

Il pourrait fonctionner à utiliser sftp au lieu de scp et de le placer en mode batch. Faites la commande batch fichier ou un tube UNIX socket de domaine et d'alimentation des commandes à ce que vous voulez les faire exécuter.

Sécurité sur cette question pourrait être un peu délicat à la fin du client.

Avez-vous essayé sshfs? Vous pouvez:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

  • /remote_dir est le répertoire que vous voulez envoyer des fichiers sur le système à vous dans l'exécution de ssh
  • /mnt/local_dir était l'emplacement de montage local

Avec cette configuration, vous pouvez simplement un fichier dans cp le et il serait local_dir être envoyé sur à sftp dans son remote_host remote_dir

Notez qu'il ya une seule connexion, donc il y a peu de la manière des frais généraux

Vous devrez peut-être utiliser le drapeau pour maintenir un -o ServerAliveInterval=15 installé localement fuse et un serveur SSH supportant (et configuré pour) <=>

Peut être que vous recherchez ceci: zssh

  

zssh (Zmodem SSH) est un programme interactif destiné à transférer des fichiers sur un ordinateur distant en utilisant le shell sécurisé (SSH). Il est destiné à être une alternative pratique à scp, ce qui permet de transférer des fichiers sans avoir à ouvrir une autre session et se ré-authentifier.

Utilisez rsync sur ssh si vous pouvez rassembler tous les fichiers à envoyer dans un seul répertoire (ou la hiérarchie des répertoires).

Si vous n'avez pas tous les fichiers dans un seul endroit, s'il vous plaît donner plus d'informations sur ce que vous voulez réaliser et pourquoi vous ne pouvez pas emballer tous les fichiers dans une archive et l'envoyer plus. Pourquoi est-il si important que chaque fichier est envoyé immédiatement? Serait-il OK si le fichier a été envoyé avec un court délai (comme lorsque 4K valeur de données a accumulé)?

Il est un joli petit problème. Je ne suis pas au courant d'une solution préemballée, mais vous pouvez faire beaucoup avec des scripts shell simples. Je vais essayer ceci au récepteur:

#!/bin/ksh
# this is receiverprogram

while true
do
  typeset -i length
  read filename  # read filename sent by sender below
  read size      # read size of file sent
  read -N $size contents  # read all the bytes of the file
  print -n "$contents" > "$filename"
done

Du côté de l'expéditeur, je créerais un tube nommé et lire de la conduite, par exemple.

mkfifo $HOME/my-connection
ssh remotehost receiver-script < $HOME/my-connection

Ensuite, pour envoyer un fichier que je vais essayer ce script

#!/bin/ksh
# this is senderprogram

FIFO=$HOME/my-connection

localname="$1"
remotename="$2"
print "$remotename" > $FIFO
size=$(stat -c %s "$localname")
print "$size" > $FIFO
cat "$localname" > $FIFO

Si la taille du fichier est grande que vous ne voulez probablement pas le lire d'un seul coup, donc quelque chose de l'ordre de

BUFSIZ=8192

rm -f "$filename"
while ((size >= BUFSIZ)); do
  read -N $BUFSIZE buffer
  print -n "$buffer" >> "$filename"
  size=$((size - BUFSIZ))
done
read -N $size buffer
print -n "$contents" >> "$filename"

Finalement, vous aurez envie d'étendre le script afin que vous puissiez passer à travers et chmod commandes chgrp. Puisque vous faites confiance le code d'envoi, il est plus facile de structurer probablement la chose pour que le récepteur appelle simplement shell sur chaque ligne eval, puis envoyer des choses comme

print filename='"'"$remotename"'"' > $FIFO
print "read_and_copy_bytes " '$filename' "$size" > $FIFO

et ensuite définir une fonction locale read_and_copy_bytes. Obtenir le droit de citer est un ours, mais sinon il devrait être simple.

Bien sûr, rien de tout cela a été testé! Mais j'espère que cela vous donne quelques idées utiles.

On dirait un emploi pour le goudron? Tuyau sa sortie à ssh, et de l'autre tuyau du côté de la sortie de ssh retour au goudron.

Je pense que le bureau GNOME utilise une connexion SSH unique lors de l'accès d'une part par le biais SFTP (SSH). Je devine que c'est ce qui se passe parce que je vois un processus SSH unique quand j'accéder à un partage à distance de cette façon. Donc, si cela est vrai, vous devriez être en mesure d'utiliser à cet effet le même programme.

La nouvelle version de GNOME utilisé GVFS par GIO afin d'effectuer tous type d'E / S à travers différents backends. Le paquet Ubuntu gvfs-bin fournit divers utilitaires de ligne de commande qui vous permettent de manipuler les backends de la ligne de commande.

D'abord, vous devrez monter votre dossier SSH:

gvfs-montage sftp: // user @ host /

Et vous pouvez utiliser la gvfs-copie pour copier vos fichiers. Je pense que tous les transferts de fichiers seront effectués par un seul processus SSH. Vous pouvez même utiliser ps pour voir quel processus est utilisé.

Si vous vous sentez plus aventureux, vous pouvez même écrire votre propre programme en C ou dans une autre langue de haut niveau qui fournit une API pour GIO.

L'une des options est Conch est une implémentation client et le serveur SSH écrit en Python en utilisant le < a href = "http://twistedmatrix.com/trac/" rel = "nofollow noreferrer"> cadre de Twsited. Vous pouvez l'utiliser pour écrire un outil qui accepte les demandes via un autre protocole (HTTP ou les sockets Unix domaine, FTP, SSH ou autre) et déclenche le transfert de fichiers sur une longue connexion SSH en cours d'exécution. En fait, j'ai plusieurs programmes de production qui utilisent cette technique pour éviter de multiples configurations de connexion SSH.

Il y avait très similaire question ici il y a quelques semaines. La réponse acceptée proposé d'ouvrir un tunnel lorsque ssh'ing à la machine à distance et d'utiliser ce tunnel pour les transferts scp.

CurlFtpFS pourrait être une solution valable pour vous.

On dirait qu'il monte juste un dossier de votre ordinateur externe à votre ordinateur via SFTP. Une fois cela fait, vous devriez être en mesure d'utiliser vos commandes régulières et tout sera cp être fait en toute sécurité.

Malheureusement, je n'ai pas pu le tester moi-même, mais laissez-moi savoir si cela fonctionne pour toi!

Modifier 1: Je suis en mesure de télécharger et tester. Comme je le craignais, il ne nécessite que le client dispose d'un serveur FTP. Cependant , je l'ai trouvé un autre programme qui a exactement le même concept que ce que vous recherchez. Vous permet de sshfs connecter à votre ordinateur client sans avoir besoin de serveur spécial. Une fois que vous avez monté un de ses dossiers, vous pouvez utiliser votre commande normale pour déplacer umount /path/to/mounted/folder des fichiers que vous avez besoin de plus. Une fois que vous avez terminé, il devrait alors être une question de sourire de <=>. Permettez-moi de savoir comment cela fonctionne!

rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

utilisera SSH pour transférer des fichiers, d'une manière non-lente

Keep it simple, écrire un petit script d'emballage qui fait quelque chose comme ça.

  1. tar les fichiers
  2. envoyer le goudron fichier
  3. untar de l'autre côté

Quelque chose comme ceci:

    <> Li -cvzf goudron fichiers test.tgz ....
  1. scp test.tgz user@other.site.com:.
  2. ssh user@other.site.com tar -xzvf test.tgz

/ Johan

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top