SSHを使用してrsyncをリモートサーバーに接続する場合、リモートパスのスペースなどをどのようにエスケープしますか?単純なバックスラッシュはローカルbashプロンプトのスペースをエスケープしますが、リモートマシンではスペースはパスの区切りとして読み取られ、そのパスの終わりを示します。
つまり、rsync -avz /path/to/source/some\ dir/ [email protected]:/path/to/dest/some\ dir/
を実行すると、リモートサーバーがそれを/path/to/dest/some/
として読み取っていて、宛先がリモートで見つからないためです。実際の宛先は単に「ではなく、いくつかのディレクトリ」であるためです。いくつか"。
同じコマンドを試してバックスラッシュとスペースをエスケープしてローカルのbashプロンプトを通過し、リモートサーバーのバックスラッシュを維持すると(合計3つのバックスラッシュ:/path/to/dest/some\\\ dir/
)、実際にリモートサーバーにバックスラッシュが送信されますただし、リモートサーバーはパスを/path/to/dest/some\/
ではなく/path/to/dest/some\ dir/
として解釈し、その後にスペースとその後の文字を削除します。
パスを引用符でラップしようとすると、パスはほぼ同じように動作し、パスをスペースで効果的に切り離します。したがって、それもローカルbashプロンプトを通過するためにのみ機能します。
最初は "-"(スペース-ハイフン-スペース)セグメントが含まれているパスを使用していて、リモートサーバーがエラーrsync: on remote machine: -: unknown option
を返していました。
では、リモートパスからスペースやハイフンなどの誤った文字を削除せずに、これをリモートサーバーで正しく機能させるにはどうすればよいですか。
イニシエーターマシンで、rsync
はリモートマシンのrsyncターゲットを呼び出すコマンドラインを構築し、sshを使用してそのコマンドラインを送信します...を単一の文字列として。その単一の文字列がシェルに渡されて解析され、引数に分割されてrsync
が実行されます。 (すでに分割され、展開され、引用符で囲まれていない)引数をバイナリセーフコンテナーにリモートrsyncにパックする代わりに、なぜそれが行われるのか私にはわかりません。
つまり、引数はtwoの異なるシェル、quoteおよびrequoteによって解析されます。通常、私は各引数を二重引用符で囲み、次に式全体を単一引用符で囲みます。場合によってはそれだけでは不十分な場合や、同じ式をローカルとリモートで使用する場合は複雑になることがあります。
その場合、私は通常、いくつかのソフトリンクを単純な、スペースなし、すべてASCIIの名前で設定し、それを使用します。
あなたが言ったときあなたは正しい軌道に乗っていました:
同じコマンドを試して、バックスラッシュとスペースをエスケープして、ローカルbashプロンプトを通過し、リモートサーバーのバックスラッシュを維持する場合
これが私が最も簡単にできる方法です:
rsync -av dir\ with\ spaces/ server.tld:"dir\ with\ spaces"
この方法も機能します。
rsync -av dir\ with\ spaces/ server.tld:dir\\\ with\\\ spaces
正確な出力と表示されているエラーを投稿できますか?
両側のrsync
をラッパースクリプトで置き換えることはできますか?
$ Sudo su -
# cd /usr/bin
# mv rsync rsync.real
# cat <<'EOF' >rsync
#!/bin/bash
logfile=/home/yourname/rsync.log
date >> "$logfile"
i=1
for arg in "$@"; do
echo "arg $i: $arg" >> "$logfile"
i=$((i+1))
done
rsync.real "$@"
EOF
# chmod +x rsync
次に、もう一度rsyncを実行します。これにより、このエスケープ方法が機能することが証明されます。
クライアント側:
Sun Feb 13 13:48:12 EST 2011
1: -av
2: dir with spaces/
3: server:dir\ with\ spaces
サーバ側:
Sun Feb 13 13:48:13 EST 2011
1: --server
2: -vlogDtpre.iL
3: .
4: dir with spaces
上記の例では、サーバーの4番目の引数(dir with spaces
)がすべて1行にあるという事実は、引用符が正しく機能していることを示しています。
これで問題が解決しない場合は、rsync -v
、rsync -vv
、またはrsync -vvv
を再実行してください。追加のデバッグ情報を提供します。
他の2つの愚かな提案:
-a
または-r
オプションを追加するのを忘れましたか?ポイントの答え:
-s(保護引数)を使用し、パスを引用符で囲みます。
rsync -savz user@server:"/my path with spaces/another dir/" "/my destination/"
スペースまたはダッシュの両方で機能します。