Le problème avec la réponse de @jakuje est: cela ne fonctionne qu'avec les sockets , mais vous ne pouvez pas utiliser d'outils UNIX standard qui attendent des fichiers avec eux:
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
bash: /tmp/sock.remote: aucun périphérique ou adresse de ce type
Il y a aussi le problème que le fichier de socket local n'est pas supprimé sur l'hôte distant; la prochaine fois que vous exécutez la même commande, vous obtenez un avertissement et le socket n'est pas recréé correctement. Vous pouvez donner la possibilité -o StreamLocalBindUnlink=yes
de ssh
dissocier cette ancienne socket, mais dans mes tests, ce n'était pas suffisant; vous devez également vous modifier sshd_config
pour contenir StreamLocalBindUnlink=yes
pour que cette option fonctionne.
Mais vous pouvez utiliser socat
ou netcat
ou tout autre outil similaire prenant en charge les sockets locaux UNIX (ce netcat-traditional
n'est PAS suffisant!) Pour utiliser le transfert de socket local pour le transfert de fichiers:
# start local process listening on local socket, which receives the data when ssh opens the connections and saves it to a local file
nc -l -N -U /tmp/sock.local >/tmp/file.local &
# connect to remote $HOST and pipe the remote file into the remote socket end
ssh \
-o ExitOnForwardFailure=yes \
-o StreamLocalBindUnlink=yes \
-R /tmp/sock.remote:/tmp/sock.local \
"$HOST" \
'nc -N -U /tmp/sock.remote </tmp/file.remote'
Vous pouvez également exécuter des commandes interactives, auquel cas vous devez utiliser ssh -t
pour allouer des ATS.
Le problème avec cette solution est que vous devez coder en dur les chemins des sockets locaux UNIX: localement, ce n'est pas vraiment un problème que vous pouvez inclure $$
dans le chemin pour le rendre unique par processus ou utilisateur un répertoire temporaire, mais sur le à distance, il vaut mieux ne pas utiliser le répertoire accessible en écriture /tmp/
comme je le fais dans mon exemple. Le répertoire doit également déjà exister au démarrage de la ssh
session. Et l'inode de socket restera même après la fermeture de la session, donc utiliser quelque chose comme "$ HOME / .ssh. $$" encombrera votre répertoire avec des inodes morts au fil du temps.
Vous pouvez également utiliser des sockets TCP liés à localhost
, ce qui vous évitera d'encombrer vos systèmes de fichiers avec des inodes morts, mais même avec eux, vous avez toujours du mal à choisir un numéro de port inutilisé (unique). Donc toujours pas idéal. ( ssh
a du code pour allouer dynamiquement les ports, mais je n'ai trouvé aucun moyen de récupérer ces informations sur l'hôte distant.)
La solution la plus simple pour copier des fichiers consiste probablement à utiliser la fonctionnalité de partage de connexion intégrée de ssh et à exécuter une commande scp
or sfrp
pendant que votre session interactive s'exécute toujours en parallèle. Voir Copier un fichier sur le système local avec ssh .
closefrom(STDERR_FILENO + 1)
appels sous le code source OpenSSH. Qu'essayez-vous de faire qui exige cela?