web-dev-qa-db-ja.com

変数をrsyncに渡すためのシェルスクリプトを支援する

Rsync用の単純なラッパーシェルスクリプトを作成しようとしています。スクリプトにファイル名を送信すると、rsyncが正しい場所を識別できないように見えます。ファイル名にはスペースが含まれています。引用符、二重引用符、バックスラッシュ引用符を使用し、rsync -s --protect-argsフラグを使用して、さまざまなバリエーションを試しました。私はついにアイデアがなくなった。これが私のスクリプトの簡略版です。

#!/bin/bash
# Example usage:
#    pull.sh "file 1" "file 2"

LOCATION="/media/WD100"
all_files=""
for file in "$@"; do
        all_files="$all_files:\"$LOCATION/$file\" "
done
# Pull the given files from homeserver to my current directory.
rsync --progress --inplace --append-verify -ave ssh username@homeserver"$all_files" .

私はこれを別の方法で書くべきですか?このスクリプトをどのように機能させるのですか?

更新:

Chazelasの答えを反映するようにスクリプトを変更しましたが、それでも機能しないようです。これが私の新しいコードです:

#!/bin/bash
# Example usage:
#    pull.sh "file 1" "file 2"

LOCATION="/media/WD100"
all_files=""
for file in "$@"; do
    all_files="$all_files\"$LOCATION/$file\" "
done
rsync --progress --inplace --append-verify -0 --files-from=<(printf '%s\0' "$all_files") -ave ssh username@homeserver: .

これを実行すると、標準の「使用法」出力が表示され、最後にこのエラーが表示されます。

rsync error: syntax or usage error (code 1) at options.c(1657) [server=3.0.9]
rsync: connection unexpectedly closed (0 bytes received so far) [Receiver]
rsync error: error in rsync protocol data stream (code 12) at io.c(605) [Receiver=3.0.9]
5
Sepero

問題は、ファイル名を引用符で囲む必要があるということですが、文字列を使用してすべてのファイル名をrsyncに渡すことができます。これは、文字列内に引用符を含む1つの長い文字列として(個別のファイル文字列パラメーターではなく)rsyncに渡されるためです。 。

変数$ @はBashの配列です。 rsyncに送信するときに、それを新しい配列に変換する必要があります。

LOCATION="/media/WD100/"
all_files=()
for file in "$@"; do
    all_files+=(":\"$LOCATION$file\"")
done
rsync --progress --inplace --append-verify -ave ssh username@homeserver"${all_files[@]}" .
1
Rucent88

使用する:

# prepend "$location" to each element of the `"$@"` array:
for file do
  set -- "$@" "$location/$file"
  shift
done

rsync ... -0 --files-from=<(printf '%s\0' "$@") user@Host: .

または:

rsync ... -0 --files-from=<(
  for file do
    printf '%s\0' "$location/$file"
  done) user@Host: .

安全のために。

これにより、ファイルのリストが名前付きパイプを介してNUL区切りのリストとしてrsyncに渡されます。

5

WD100のすべてのコンテンツを現在の場所にコピーしているので、rsyncにディレクトリのコンテンツを同期させます。

 rsync --progress --inplace --append-verify -ave ssh username @ homeserver:/ media/WD100/./

rsyncは、パスの末尾のスラッシュに応じて動作が異なります。スラッシュがない場合はディレクトリオブジェクトを再帰的にコピーしますが、スラッシュがある場合はディレクトリの内容を再帰的にコピーします。

これが関連する rsync manual のセクションです。

ソースの末尾のスラッシュは、この動作を変更して、宛先に追加のディレクトリレベルを作成しないようにします。ソースの末尾の/は、namerqでディレクトリをlqcopyするのではなく、このdirectoryrqの内容をlqcopyすることを意味すると考えることができますが、どちらの場合も、包含ディレクトリの属性は宛先の包含ディレクトリに転送されます。つまり、次の各コマンドは、/ dest/fooの属性の設定を含め、同じ方法でファイルをコピーします。

rsync -av /src/foo /dest
rsync -av /src/foo/ /dest/foo
0
ir0h