Lors de la connexion à un hôte avec SSH, généralement trois « tubes » sont prévus entre l' hôte et l' invité, pour stdin
, stdout
et stderr
.
Existe-t-il une option de ligne de commande pour créer des transferts pour des descripteurs de fichiers supplémentaires ( 3
et suivants)?
Par exemple, j'aimerais faire
ssh --forwardfd=10:3 remotehost 'echo test >&3'
qui imprimerait 'test' dans le descripteur de fichier ouvert localement 10.
ssh
pipe
file-descriptors
mic_e
la source
la source
closefrom(STDERR_FILENO + 1)
appels sous le code source OpenSSH. Qu'essayez-vous de faire qui exige cela?stdin
/out
/err
, mais AFAIK, aucun serveur / client ne prend en charge de quelque manière que ce soit cette fonctionnalité.infinite-output-cmd | ssh user@host bash /proc/self/fd/3 3< local-script-to-execute-remotely.sh
--forwardfd
ne devrait même pas être nécessaire.ssh
pourrait vérifier quels sont les descripteurs de fichiers ouverts avant d'ouvrir toute autre chose, et les transmettre automatiquement aux mêmes descripteurs de fichiers sur le côté distant. Cela pourrait être totalement transparent comme mon exemple. Je me demande combien il serait difficile de corrigerssh
cela. Comme vous l'avez dit, cela pourrait être délicat en fonction des raisons derrière celaclosefrom(STDERR_FILENO + 1)
.Réponses:
Vous pouvez le faire en utilisant le transfert de socket, disponible depuis openssh-6.7. C'est une sorte de pipe. Cette technique est décrite par exemple ici: http://www.25thandclement.com/~william/projects/streamlocal.html
Vous obtiendrez un itinéraire bidirectionnel pour vos données. Il y a un exemple avec mysql:
la source
Je suis sûr que cela devrait être possible. Je ne peux que suggérer un hack où vous utilisez des connexions ssh supplémentaires pour chacune transporter une autre paire de descripteurs de fichiers. Par exemple, le script de preuve de concept suivant effectue un premier ssh pour exécuter une commande fictive (veille) pour connecter les fds locaux 5 et 6 aux stdin et stdout distants, en supposant que ces fds sont ceux que vous souhaitez ajouter au 0,1 habituel, 2.
Ensuite, le vrai ssh est terminé, et sur la télécommande, il connecte les fds distants 5 et 6 à la stdin et à la sortie standard de l'autre ssh.
À titre d'exemple, ce script transmet une page de manuel compressée à la télécommande, qui la décompresse et la fait passer par man. Le stdin et le stdout du vrai ssh sont toujours disponibles pour d'autres choses.
la source
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'
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
dessh
dissocier cette ancienne socket, mais dans mes tests, ce n'était pas suffisant; vous devez également vous modifiersshd_config
pour contenirStreamLocalBindUnlink=yes
pour que cette option fonctionne.Mais vous pouvez utiliser
socat
ounetcat
ou tout autre outil similaire prenant en charge les sockets locaux UNIX (cenetcat-traditional
n'est PAS suffisant!) Pour utiliser le transfert de socket local pour le transfert de fichiers: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 lassh
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
orsfrp
pendant que votre session interactive s'exécute toujours en parallèle. Voir Copier un fichier sur le système local avec ssh .la source