rsyncを使用してファイルをリモートの場所に移動しようとしています。
ファイル名はDRRS_(H264).mp4です。
しかし、私が試したとき:
rsync -azR output.mp4 [email protected]:encoded/somepath/DRRS_(H264).mp4
bash:予期しない表示 '( 'の近くで構文エラーが発生しました。
しかし、どのようにカプセル化するのか理解できません。
私は試した:
rsync -azR output.mp4 [email protected]:"encoded/somepath/DRRS_(H264).mp4"
そして
rsync -azR output.mp4 "[email protected]:encoded/somepath/DRRS_(H264).mp4"
成功しませんでした。
ベストアンサー1
-s|--protect-args
このオプションを使いたいですrsync
。
これがなければ、次の部分が:
そのままリモートシェルに渡されるので、そのシェルのコンストラクタを使用して転送するリストを作成できます。
これにより、リモートシェルがzshであることを知っている場合は、次のことができます。
rsync host:'*(.)' there
通常のファイルのみが転送されます。またはcsh
///を使用してくださいbash
:zsh
ksh
rsync host:'{foo,bar}.txt' there
または:
rsync file 'host:"$HOME/$(uname)-file"'
これは、ランダムな名前のファイルを簡単に転送できないことを意味します。
を使用すると、-s
文字rsync
列はリモートシェルに渡されません。代わりに、リモートホストのサーバーに帯域内に渡すため、リモートrsync
シェルはそれを解釈しません。
(
ほとんどのシェルには特に)
、各シェルごとに異なるリモートシェルの構文を使用してエスケープする必要があります。
代わりに使用することをお勧めします-s
。
rsync -sazR output.mp4 [email protected]:'encoded/somepath/DRRS_(H264).mp4'
ただし、rsync
(自分の)ワイルドカードは、渡された文字列に対してまだ行われます(ターゲットについても!)。したがって、まだできませんrsync
。 exampleというファイルを処理するには、*
バックスラッシュを使用してエスケープする必要があります(少なくとも今回はリモートシェルとは関係ありません)。
rsync -sazR output.mp4 [email protected]:'\*'
したがって、名前を含むファイルを転送するには、次のものを$1
使用する必要があります。
file=$1
rsync_escaped_file=$(
printf '%s.\n' "$file" | sed 's/[[*?]/\\&/g'
)
rsync_escaped_file=${rsync_escaped_file%.}
rsync -s ... "user@host:$rsync_escaped_file"
ローカルシェルがあり、bash
リモートユーザーのログインシェルがbash
同じバージョンであることを知っている場合は、printf %q
代わりにリモートシェル固有の文字をエスケープすることを使用できます-s
。
LC_ALL=C printf -v shell_escaped_file %q "$1"
rsync ... "user@host:$shell_escaped_file"
リモートホストのログインシェルがBourneに似ていて(Bourne、ksh、yash、zsh、bash、ash ...)、SSHクライアントとサーバーが環境変数を渡すことを許可していることがわかっている場合でもこれをLC_*
行うことができます(繰り返しますが、使用しない-s
)。 :
LC_FILE=$1 rsync ... 'user@host:"$LC_FILE"'
注1:-s
|--protect-args
このオプションはバージョン3.0.0(2008)以降でのみ利用可能です。
ノート2:rsync
文書では-s
|--protect-args
将来のバージョンでデフォルトになる可能性があることを警告しますrsync
(将来の保証のために--no-protect-args
その効果を望まない場合は、使用を開始することをお勧めします)。