Das Problem mit der Antwort von @jakuje ist: Es funktioniert nur mit Sockets , aber Sie können keine Standard-UNIX-Tools verwenden, die Dateien mit ihnen erwarten :
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
bash: /tmp/sock.remote: Kein solches Gerät oder keine solche Adresse
Außerdem besteht das Problem, dass die lokale Socket-Datei auf dem Remote-Host nicht gelöscht wird. Wenn Sie das nächste Mal denselben Befehl ausführen, wird eine Warnung angezeigt und der Socket wird nicht ordnungsgemäß neu erstellt. Sie können die Option -o StreamLocalBindUnlink=yes
zum ssh
Trennen dieser alten Socket geben, aber in meinen Tests war es nicht genug; Sie müssen Sie auch bearbeiten, um sshd_config
zu enthalten, StreamLocalBindUnlink=yes
damit diese Option funktioniert.
Aber können Sie verwenden , socat
oder netcat
oder ein anderes ähnliches Werkzeug unterstützt UNIX lokale Steckdosen ( netcat-traditional
ist nicht genug!) , Um die lokale Socket - Weiterleitung für die Dateiübertragung zu verwenden:
# 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'
Sie können auch interaktive Befehle ausführen. In diesem Fall sollten Sie ssh -t
TTYs zuweisen.
Das Problem bei dieser Lösung ist, dass Sie die Pfade der lokalen UNIX-Sockets fest codieren müssen: Lokal ist dies kein so großes Problem, wie Sie es $$
in den Pfad aufnehmen können, um ihn pro Prozess oder Benutzer als temporäres Verzeichnis eindeutig zu machen, sondern auf der Remote-End verwenden Sie besser nicht das von der Welt beschreibbare Verzeichnis /tmp/
wie in meinem Beispiel. Das Verzeichnis muss auch bereits beim ssh
Start der Sitzung vorhanden sein. Und die Socket-Inode bleibt auch nach dem Schließen der Sitzung erhalten. Wenn Sie also so etwas wie "$ HOME / .ssh. $$" verwenden, wird Ihr Verzeichnis im Lauf der Zeit mit toten Inodes überfüllt.
Sie können auch TCP-Sockets verwenden, an localhost
die Sie gebunden sind, um zu verhindern , dass Ihre Dateisysteme mit toten Inodes überfrachtet werden. Trotzdem müssen Sie immer noch Probleme haben, eine (eindeutige) nicht verwendete Portnummer zu wählen. Also immer noch nicht ideal. ( ssh
Hat Code zum dynamischen Zuweisen von Ports, aber ich habe keine Möglichkeit gefunden, diese Informationen auf dem Remote-Host abzurufen.)
Die wahrscheinlich einfachste Lösung zum Kopieren von Dateien besteht darin, die integrierte Verbindungsfreigabefunktion von ssh zu verwenden und einen scp
oder sfrp
-Befehl auszuführen, während Ihre interaktive Sitzung noch parallel ausgeführt wird. Siehe Eine Datei mit ssh zurück auf das lokale System kopieren .
closefrom(STDERR_FILENO + 1)
Aufrufe unter dem OpenSSH-Quellcode. Was versuchst du zu tun, das dies verlangt?