1

bashスクリプト内の1回の呼び出しで複数のディレクトリをrsyncしようとしていますが、パスを引用するための構文で問題が発生しています。

これが私が試していることです:

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder1' 'folder2')
backupitems=(${backupitems[@]/#/\"$backuppath})
backupitems=(${backupitems[@]/%/\"})
backup=${backupitems[@]}

rsync ${backup} /path/to/destination

そのようなファイルやディレクトリがないというlink_statエラーが"/path/to/current/directory"/path/to/backup/folders/folder1""発生し、folder2でも同じエラーが発生します。したがって、引用符で囲まれたパスを希望どおりに生成しているように見えますが、rsyncはパスを相対パスとして解釈し、先頭の現在のディレクトリへのパスを追加しています。私がそうすればrsyncは正しく動作します

backuppath='path/to/backup/folders/folder1'
rsync "${backuppath}" /path/to/destination

引用符をrsyncコマンドに入れますが、複数のディレクトリを長い単一のパスとして扱うため、1つの変数内の複数のフォルダーでこれを行うことはできません。2番目の方法を使用して、フォルダーをループし、各フォルダーでrsyncを呼び出すことでスクリプトを機能させましたが、スクリプトの他の部分がフォルダーを処理する方法のため、この方法は少し厄介なので、最初の方法を取得したいと思います。クイックフィックスがある場合に機能します。

編集:

上記の最上位バージョンでは、ディレクトリ名にスペースが含まれていないため、次のコマンドを使用していset -vxます。rsync'"/ path / to / backup / folder / folder1"''" / path / to / backup / folder / folder2 "'/ path / to / destination

次のエラーメッセージが表示されます。

rsync: link_stat "/path/to/current/directory/"/path/to/backup/folders/folder1"" failed: No such file or directory (2)

@kdubsによって提案されたバージョンを使用する場合、パスにスペースがない場合はすべてが機能します。

パスにスペースがある場合、kdubsバージョンは次のコマンドになります。

rsync / path / to / backup / folder / folder1 / path / to / backup / folder / folder2 / path / to / destination

およびエラー:

rsync: link_stat "/path/to/back" failed: No such file or directory (2)
rsync: link_stat "/path/to/back up/up/folder1" failed: No such file or directory (2)

私の最初のバージョンでは、スペースを操作するために追加の調整が必要です。これは、[@]で配列を展開し、展開を()で囲むことによって新しい配列を作成すると、パス内のスペースがパスを複数の配列要素に分割するためです(Toninの回答を参照)下)。

4

3 に答える 3

4

変数に引用符を埋め込んでも、何の役にも立ちません。この種のことを行う最善の方法は、変数を展開するときに変数を二重引用符で囲み、配列を次のように展開することです。これにより、 "${arrayname[@]}"bash は、配列の各要素にスペースやその他の要素が含まれていても、個別の単語として扱います。シェルのメタ文字。注意が必要なのは、配列の各要素の前に $backuppath を付けることですが、それには正しいアプローチがあります (値ではなく引用符で囲む以外は)。

backuppath='/path/with spaces/'
backupitems=('folder 1' 'folder 2')   # declare -a is optional
backupitempaths=("${backupitems[@]/#/$backuppath}")

rsync "${backupitempaths[@]}" /path/to/destination
于 2012-12-28T06:51:16.153 に答える
1

スクリプトの問題は、bash が配列の要素を定義する方法にあります。要素はスペースで区切られます。したがって、変更した配列要素を配列に再割り当てすると、実際には、最初に作成したよりも多くの要素が作成されます。echo ${#backupitems[@]}配列宣言と各代入の後にを追加することで確認できます。

最後に、変数の配列をフラット化すると$backup、bash は相対パスが指定されていると rsync に信じ込ませることで状況をさらに悪化させます。

これを解決するために、ファイル名 (またはパスの任意の場所) のスペースを処理する次のスクリプトを使用します。

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder 1' 'folder 2')
PIFS=$IFS
# prevents creating new elements from the original array
IFS=''
backupitems=(${backupitems[@]/#/$backuppath})

rsync ${backupitems[@]} /path/to/destination
IFS=$PIFS

スクリプトはIFS、配列を作成するときのレコード区切りに関する bash の動作を変更する変数を再宣言します。ただし、$backup変数はもう使用できないという点で、スクリプトとはわずかな違いがあります。それ以外の場合は、実際に使用する前に配列をフラット化します。それが要件ではなかったことを願いましょう。

于 2012-12-27T20:52:25.620 に答える
0

それらの引用符を取り除きます:

backuppath='/path/to/backup/folders/'
declare -a backupitems=('folder1' 'folder2')
backupitems=(${backupitems[@]/#/$backuppath})
backup=${backupitems[@]}

rsync ${backup} /path/to/destination
于 2012-12-27T19:37:48.810 に答える