@jakujeからの答えの問題は、socketsでのみ機能するが、それらを含むファイルを期待する標準のUNIXツールを使用できないことです。
ssh -R/tmp/sock.remote:/tmp/sock.local "$HOST" 'LANG=C cat >/tmp/sock.remote'
bash:/tmp/sock.remote:そのようなデバイスまたはアドレスはありません
また、リモートホスト上でローカルソケットファイルが削除されないという問題もあります。次に同じコマンドを実行すると、警告が表示され、ソケットが正しく再作成されません。古いソケットのリンクを解除するオプション-o StreamLocalBindUnlink=yes
を指定できますssh
が、私のテストでは十分ではありませんでした。また、そのオプションを機能さsshd_config
せるにはStreamLocalBindUnlink=yes
、編集する必要があります。
しかし、あなたは使用することができますsocat
かnetcat
またはサポートする任意の他の同様のツールUNIXローカルソケットが(netcat-traditional
あるはありません、ファイル転送のためのローカルソケット転送を使用するのに十分な!):
# 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'
対話型コマンドを実行することもできます。この場合、ssh -t
TTYの割り当てに使用する必要があります。
このソリューションの問題は、UNIXローカルソケットのパスをハードコーディングする必要があることです。ローカルでは$$
、プロセスまたはユーザーごとに一意にするためにパスに含めることができるので、ローカルではそれほど問題ではありませんが、リモートエンドの方/tmp/
が、私の例のように、world-writeableディレクトリを使用しない方がよいでしょう。ディレクトリは、ssh
セッションの開始時にすでに存在している必要があります。また、ソケットiノードはセッションが閉じられた後も残るため、「$ HOME / .ssh。$$」のようなものを使用すると、時間の経過とともにディレクトリに不要なiノードが散らかってしまいます。
にバインドされたTCPソケットを使用することもできますlocalhost
。これにより、ファイルシステムがデッドiノードで乱雑になるのを防ぐことができますが、それでも、(一意の)未使用のポート番号を選択する問題があります。まだ理想的ではありません。(ssh
ポートを動的に割り当てるコードがありますが、リモートホストでその情報を取得する方法が見つかりませんでした。)
おそらく、ファイルをコピーする最も簡単な解決策は、sshの組み込みの接続共有機能を使用し、対話型セッションが並行して実行されている間にscp
or sfrp
コマンドを実行することです。sshを使用してローカルシステムにファイルをコピーするを参照してください。
closefrom(STDERR_FILENO + 1)
OpenSSHソースコードの下でのさまざまな呼び出しを考えると、おそらくトリッキーなソース編集なしではありません。これを要求していることは何ですか?