ローカルシェルを使用して2つのリモートホスト間でファイルを転送したいのですが、2つのリモートが次のように指定されている場合、rsyncは同期をサポートしていないようです。
$ rsync -vuar Host1:/var/www Host2:/var/www
The source and destination cannot both be remote.
同様の結果を達成するために使用できる他の回避策/コマンドは何ですか?
あなたが発見したように、リモートソースとリモート宛先でrsyncを使用することはできません。 2つのサーバーが互いに直接通信できない場合、sshを使用してローカルマシン経由でトンネリングすることが可能です。
の代わりに
rsync -vuar Host1:/var/www Host2:/var/www
あなたはこれを使うことができます
ssh -R localhost:50000:Host2:22 Host1 'rsync -e "ssh -p 50000" -vuar /var/www localhost:/var/www'
ご参考までに、-R
オプションは、(ローカルマシンを介して)Host1のポート50000からHost2のポート22にマップするリバースチャネルを設定します。 Host1からHost2への直接接続はありません。
1つのホストにログインしてから別のホストにコピーしたくない理由を言わなかったので、私の理由と解決策の1つを共有します。
1つのマシンにログインしてから、もう1つのマシンにrsyncできませんでした。どちらのホストにも、もう1つのマシンにログインできるSSHキーがなかったためです。ログイン中にSSHエージェント転送を使用して最初のホストがSSHキーを使用できるようにすることで、これを解決しました。
警告: SSH転送により、ログイン中にホストがSSHキーを使用できるようになります。彼らはあなたのキーをコピーすることはできませんが、それを使って他のマシンにログインすることができます。リスクを理解し、信頼できないマシンにエージェント転送を使用しないようにしてください。
次のコマンドは、SSHエージェント転送を使用して、Host1
からHost2
への直接接続を開きます。これには、コマンドを実行しているマシンが転送のボトルネックにならないという利点があります。
ssh -A Host1 rsync -vuar /var/www Host2:/var/www
私はロアイマの答えが好きですが、パスはどちらの例でも同じです。以下は機能しないことが確認されています。
rsync -vuar Host1:/Host1/path Host2:/Host2/path
ただし、これはデフォルトです(-R
オプションからlocalhostの明示的なbind_addressを省略しています)。
ssh -R 50000:Host2:22 Host1 'rsync -e "ssh -p 50000" -vuar /Host1/path localhost:/Host2/path'
Host1の秘密鍵とHost2の公開鍵を使用して、2つのリモートホスト間でSSH鍵を正しく設定する必要があることに注意してください。
接続をデバッグするには、これを2つの部分に分割し、詳細なステータスを追加します。
localhost$ ssh -v -R 50000:Host2:22 Host1
これが機能する場合、Host1にシェルがあります。次に、Host1からrsyncコマンドを試してください。これを別のウィンドウで行うことをお勧めします。これにより、詳細なssh情報がrsyncステータス情報と混同されなくなります。
Host1$ rsync -e "ssh -p 50000" -vuar /Host1/path localhost:/Host2/path
Bashスクリプト構文でroaimaによる回答を再フォーマットします(明確にするために行継続文字 '\'を追加します)私はランダムにポート22000を選びました...
SOURCE_USER=user1
SOURCE_Host=hostname1
SOURCE_PATH=path1
TARGET_USER=user2
TARGET_Host=host2
TARGET_PATH=path2
ssh -l $TARGET_USER -A -R localhost:22000:$TARGET_Host:22 \
$SOURCE_USER@$SOURCE_Host "rsync -e 'ssh -p 22000' -vuar $SOURCE_PATH \
$TARGET_USER@localhost:$TARGET_PATH"
理想的な方法は、これらのサーバーの1つでrsync
を実行することです。ただし、リモートサーバーでスクリプトを実行したくない場合は、ローカルシステムでスクリプトを実行し、sshを実行してrsyncを実行できます。
ssh user@$Host1 <<ENDSSH >> /tmp/rsync.out 2>&1 rsync -vuar /var/www Host2:/var/www ENDSSH
また、ご存知かもしれませんが、rysncは一方向の同期を行います。双方向の同期が必要な場合は、osync( https://github.com/deajan/osync )を確認できます。私はそれを使って、それが役に立ったと思いました。
いずれかのコンピューターでrsyncd(サーバー)を実行できます。
これは私が採用しているアプローチです。sshを使用して(rsyncの言い回しで)「ソース」がパスワードなしで「宛先」にrootとしてアクセスできるようにしたくないので(rsyncでSSHトンネリングを使用するために必要です)スクリプト)
私の場合、移行先コンピューターにrsyncdサーバーをセットアップし、ソースPCから許可された単一のユーザーを使用して、ソース側からrsyncを使用しました。
よく働く。
使いやすいスクリプト
長年にわたり、私はここで他のすべての答えと同じトリックを多かれ少なかれ同じように何度もこれを行ってきました。ただし、詳細を間違えたり、問題の解明に多くの時間を費やしたりするのは非常に簡単であるため、以下のスクリプトを考え出しました。
ssh -A
認証データの伝達に失敗します(回避策は根本的な原因を見つけるよりも簡単だったため、なぜこれが発生するのかわからない)スクリプトの使用方法
仕組み
私が言ったように、ここでは他のすべての答えと同じトリックを使用しています:
-R
localhostからHost1にsshするオプションと同時に、ポート転送を設定して、Host1がlocalhost経由でHost2に接続できるようにします(-R localhost:$FREE_PORT:$TARGET_ADDR_PORT
)-A
2番目のsshシャネルの簡単な認証を可能にするオプションMy this IS複雑!簡単な方法はありますか?
すべてまたはほとんどのバイトをソースから宛先にコピーする場合、[〜#〜] far [〜#〜]tar
を使用する方が簡単です。
ssh $SOURCE_Host "tar czf - $SOURCE_PATH" \
| ssh $TARGET_Host "tar xzf - -C $TARGET_PATH/"
スクリプト
#!/bin/bash
#-------------------SET EVERYTHING BELOW-------------------
# whatever you type after ssh to connect to SOURCE/TARGE Host
# (e.g. 1.2.3.4:22, user@Host:22000, ssh_config_alias, etc)
# So if you use "ssh foo" to connect to SOURCE then
# you must set SOURCE_Host=foo
SOURCE_Host=host1
TARGET_Host=host2
# The IP address or hostname and ssh port of TARGET AS SEEN FROM LOCALHOST
# So if ssh -p 5678 [email protected] will connect you to TARGET then
# you must set TARGET_ADDR_PORT=1.2.3.4:5678 and
# you must set TARGET_USER=someuser
TARGET_ADDR_PORT=1.2.3.4:5678
TARGET_USER=someuser
SOURCE_PATH=/mnt/foo # Path to rsync FROM
TARGET_PATH=/mnt/bar # Path to rsync TO
RSYNC_OPTS="-av --bwlimit=14M --progress" # rsync options
FREE_PORT=54321 # just a free TCP port on localhost
#---------------------------------------------------------
echo -n "Test: ssh to $TARGET_Host: "
ssh $TARGET_Host echo PASSED| grep PASSED || exit 2
echo -n "Test: ssh to $SOURCE_Host: "
ssh $SOURCE_Host echo PASSED| grep PASSED || exit 3
echo -n "Verifying path in $SOURCE_Host "
ssh $SOURCE_Host stat $SOURCE_PATH | grep "File:" || exit 5
echo -n "Verifying path in $TARGET_Host "
ssh $TARGET_Host stat $TARGET_PATH | grep "File:" || exit 5
echo "configuring ssh from $SOURCE_Host to $TARGET_Host via locahost"
ssh $SOURCE_Host "echo \"Host tmpsshrs; ControlMaster auto; ControlPath /tmp/%u_%r@%h:%p; hostname localhost; port $FREE_PORT; user $TARGET_USER\" | tr ';' '\n' > /tmp/tmpsshrs"
# The ssh options that will setup the tunnel
TUNNEL="-R localhost:$FREE_PORT:$TARGET_ADDR_PORT"
echo
echo -n "Test: ssh to $SOURCE_Host then to $TARGET_Host: "
if ! ssh -A $TUNNEL $SOURCE_Host "ssh -A -F /tmp/tmpsshrs tmpsshrs echo PASSED" | grep PASSED ; then
echo
echo "Direct authentication failed, will use plan #B:"
echo "Please open another terminal, execute the following command"
echo "and leave the session running until rsync finishes"
echo "(if you're asked for password use the one for $TARGET_USER@$TARGET_Host)"
echo " ssh -t -A $TUNNEL $SOURCE_Host ssh -F /tmp/tmpsshrs tmpsshrs"
read -p "Press [Enter] when done..."
fi
echo "Starting rsync"
ssh -A $TUNNEL $SOURCE_Host "rsync -e 'ssh -F /tmp/tmpsshrs' $RSYNC_OPTS $SOURCE_PATH tmpsshrs:$TARGET_PATH"
echo
echo "Cleaning up"
ssh $SOURCE_Host "rm /tmp/tmpsshrs"
これを使ってみてください。わたしにはできる。
ssh src_user@src_Host 'rsync -av /src/dir/location/ dest_user@dest_Host:/dest/dir/loc/'
追加情報として:
ジャンプホストを使用して他の2台のマシンを接続しているが、お互いに直接到達できない場合は、これらの2台のマシン間で(ジャンプホスト上で)sshfsを媒体として使用できます。
$ mkdir ~/sourcepath ~/destpath
$ sshfs sourcehost:/target/dir ~/sourcepath
$ sshfs desthost:/target/dir ~/destpath
$ rsync -vua ~/sourcepath ~/desthpath
SSHFSはジャンプホストに2つのパスを提供し、rsyncはいつものようにファイルの同期を管理します(ローカルで行われる点が異なります)。