10

一連のファイルを反復処理し、それらのいくつかを呼び出すプログラムを作成しました。

scp <file> user@host:<remotefile>

ただし、私の場合、転送する必要がある小さなファイルが何千もある可能性があり、scp はそれらのそれぞれに対して新しい ssh 接続を開いているため、かなりのオーバーヘッドがあります。

接続を維持する1つのプロセスを実行し続け、単一のファイルをコピーするために「リクエスト」を送信できるソリューションがないかどうか疑問に思っていました。

理想的には、最初に単一のプロセス (1) を開始できるように、送信プログラムと受信プログラムの組み合わせを探しています。

ssh user@host receiverprogram

そして、ファイルごとにコマンド (2) を呼び出します。

senderprogram <file> <remotefile>

(2) の出力を (1) の入力にパイプすると、ファイルが転送されます。最後に、プロセス (1) に何らかの終了シグナルを送信するだけです。

送信側プログラムと受信側プログラムは、Unix 用のオープン ソース C プログラムであることが望ましいです。それらは、パイプの代わりにソケット、またはその他の創造的なソリューションを使用して通信する場合があります。

ただし、各ファイルは反復処理の時点で転送されるという重要な制約scpがあります。ファイルのリストを収集してから、 の 1 つのインスタンスを呼び出して、最後にすべてのファイルを一度に転送することは受け入れられません。また、受信ホストへの単純なシェル アクセスしかありません。

更新: ssh の多重化機能を使用して接続オーバーヘッドの問題の解決策を見つけました。以下の私自身の回答を参照してください。それでも、ここで説明する送信者/受信者プログラムが存在するかどうかを知りたいので、報奨金を開始しています。xmodem/ymodem/zmodem など、使用できるものがあるはずです。

4

14 に答える 14

23

私は別の角度から解決策を見つけました。バージョン3.9以降、OpenSSHはセッションの多重化をサポートしています。1つの接続で複数のログインセッションまたはファイル転送セッションを実行できます。これにより、接続ごとのセットアップコストを回避できます。

質問の場合、最初に接続を開いて、特定の場所に-Mソケット()を備えたコントロールマスター()を設定できます。-Sセッションは必要ありません(-N)。

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

scp次に、ファイルごとに呼び出して、同じソケットを使用するように指示できます。

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

このコマンドはほぼ瞬時にコピーを開始します!

通常のssh接続に制御ソケットを使用することもできます。これにより、すぐに開きます。

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

制御ソケットが使用できなくなった場合(たとえば、マスターを強制終了したため)、これは通常の接続にフォールバックします。詳細については、この記事を参照してください。

于 2009-02-06T07:20:46.987 に答える
4

この方法は機能しますが、他のことについては、この一般的なアプローチは多かれ少なかれ正しいものです。

(
iterate over file list
  for each matching file
   echo filename
) | cpio -H newc -o | ssh remotehost cd location \&\& | cpio -H newc -imud
于 2009-02-15T23:35:41.503 に答える
4

scp の代わりに sftp を使用し、バッチ モードにするとうまくいく場合があります。バッチ コマンド ファイルをパイプまたは UNIX ドメイン ソケットにして、必要に応じてコマンドを実行します。

これに関するセキュリティは、クライアント側では少し難しいかもしれません。

于 2009-02-05T12:38:37.487 に答える
4

試しましたsshfsか?あなたは出来る:

sshfs remote_user@remote_host:/remote_dir /mnt/local_dir

どこ

  • /remote_dirsshing先のシステムでファイルを送信したいディレクトリでした
  • /mnt/local_dirローカルのマウント場所でした

このセットアップではcp、ファイルを に入れるだけで、local_dirsftpremote_hostremote_dir

単一の接続があるため、オーバーヘッドがほとんどないことに注意してください

無期限の接続-o ServerAliveInterval=15を維持するには、フラグを使用する必要がある場合があります

fuseローカルにインストールし、SSH サーバーをサポートする (および構成する)必要があります。sftp

于 2009-02-15T22:51:59.643 に答える
3

これを探しているかもしれません: ZSSH

zssh (Zmodem SSH) は、セキュア シェル (ssh) を使用してリモート マシンにファイルを対話的に転送するためのプログラムです。scp の便利な代替手段として意図されており、別のセッションを開いて自分自身を再認証することなくファイルを転送できます。

于 2009-02-12T22:54:00.207 に答える
2

It's a nice little problem. I'm not aware of a prepackaged solution, but you could do a lot with simple shell scripts. I'd try this at the receiver:

#!/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

At the sender side I would create a named pipe and read from the pipe, e.g.,

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

Then to send a file I'd try this 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

If the file size is large you probably don't want to read it at one go, so something on the order of

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"

Eventually you'll want to extend the script so you can pass through chmod and chgrp commands. Since you trust the sending code, it's probably easiest to structure the thing so that the receiver simply calls shell eval on each line, then send stuff like

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

and then define a local function read_and_copy_bytes. Getting the quoting right is a bear, but otherwise it should be straightforward.

Of course, none of this has been tested! But I hope it gives you some useful ideas.

于 2009-02-12T04:14:25.700 に答える
2

単一のディレクトリ (またはディレクトリの階層) に送信するすべてのファイルを収集できる場合は、ssh 経由で rsync を使用します。

すべてのファイルを 1 か所にまとめていない場合は、達成したいことと、すべてのファイルをアーカイブにまとめて送信できない理由について、さらに詳しい情報を提供してください。各ファイルをすぐに送信することが非常に重要なのはなぜですか? 少し遅れて(4K分のデータが溜まったときなど)ファイルを送っても大丈夫でしょうか?

于 2009-02-05T16:38:50.623 に答える
1

タールの仕事のようですか?その出力を ssh にパイプし、反対側で ssh 出力を tar に戻します。

于 2009-02-05T12:37:55.413 に答える
1

SFTP (SSH) 経由で共有にアクセスする場合、GNOME デスクトップは単一の SSH 接続を使用すると思います。この方法でリモート共有にアクセスすると、単一の SSH プロセスが表示されるため、これが起こっていると推測しています。したがって、これが本当なら、同じプログラムをこの目的に使用できるはずです。

新しいバージョンの GNOMEは、さまざまなバックエンドを介してあらゆる種類の I/O を実行するために、GIOを介して GVFS を使用しました。Ubuntu パッケージ gvfs-bin には、コマンド ラインからバックエンドを操作できるさまざまなコマンド ライン ユーティリティが用意されています。

まず、SSH フォルダーをマウントする必要があります。

gvfs-mount sftp://user@host/

そして、gvfs-copy を使用してファイルをコピーできます。すべてのファイル転送は、単一の SSH プロセスを介して実行されると思います。ps を使用して、使用されているプロセスを確認することもできます。

もっと冒険したい場合は、C または GIO に API を提供する他の高級言語で独自のプログラムを作成することもできます。

于 2009-02-11T10:39:43.477 に答える
1

数週間前に非常によく似た質問がここにありました。受け入れられた回答は、リモートマシンに ssh するときにトンネルを開き、そのトンネルを scp 転送に使用することを提案しました。

于 2009-02-16T19:59:42.483 に答える
1

おそらく、 CurlFTPFSが有効なソリューションになるかもしれません

SFTP経由で外部コンピューターのフォルダーをコンピューターにマウントするだけのようです。それが完了すると、通常のコマンドを使用できるようにcpなり、すべてが安全に行われます.

残念ながら、自分でテストすることはできませんでしたが、うまくいくかどうか教えてください!

編集 1: ダウンロードしてテストすることができました。私が恐れていたように、クライアントには FTP サーバーが必要です。 ただし、探しているものとまったく同じ概念を持つ別のプログラムを見つけました。 sshfs特別なサーバーを必要とせずに、クライアント コンピューターに接続できます。フォルダの 1 つをマウントしたら、通常のcpコマンドを使用して、必要なファイルをさらに移動できます。終わったら、笑顔の問題になるはずですumount /path/to/mounted/folder。これがどのように機能するか教えてください!

于 2009-02-17T06:22:44.153 に答える
0
rsync -avlzp user@remotemachine:/path/to/files /path/to/this/folder

This will use SSH to transfer files, in a non-slow way

于 2009-02-12T04:17:29.500 に答える
0

シンプルに保ち、このようなことを行う小さなラッパー スクリプトを作成します。

  1. ファイルをtarします
  2. tarファイルを送る
  3. 反対側の untar

このようなもの:

  1. tar -cvzf test.tgz ファイル ....
  2. scp test.tgz user@other.site.com:.
  3. ssh user@other.site.com tar -xzvf test.tgz

/ヨハン

于 2009-02-12T20:35:32.457 に答える