動的rsyncコマンドで二重引用符をエスケープします。

動的rsyncコマンドで二重引用符をエスケープします。

現在、ユーザーのホームディレクトリをランダムに選択したディレクトリにコピーし、rsyncを使用して同じディレクトリ(存在する場合)から最後に作成されたコピーに接続するスクリプトを作成しています。

コマンドは次のように構築され実行されます。

...
[ -z $LAST_SNAPSHOT ] && LINK_DEST="" || LINK_DEST="--link-dest \"$BACKUP_ROOT/$LAST_SNAPSHOT\""
...

/usr/bin/rsync $OPTS $EXCLUDES $LINK_DEST "$MASTER/" "$NEW_SNAPSHOT"

rsyncスクリプトを実行すると、次のエラーが発生します。

--link-dest arg does not exist: "/home/backuptest/dest/backuptest/20180619_134044"

これは、ディレクトリが実際には存在しないが存在する場合に予想されます。

変数を生成するコードから引用符を削除すると、$LINK_DEST次のコードが生成されます。

[ -z $LAST_SNAPSHOT ] && LINK_DEST="" || LINK_DEST="--link-dest $BACKUP_ROOT/$LAST_SNAPSHOT"

これでrsyncは文句を言わない。パスにスペースがないようにしたいので、二重引用符が必要です。

エラーが何であるかを理解できません。 rsyncを呼び出す方法ですか、それともシェルを誤解していますか?

ベストアンサー1

エスケープされた二重引用符は、ファイル名のリテラル文字として扱われます。を使用しているので、bash配列を使用してそれを処理できます。

linkDest=()
[[ -n "$LAST_SNAPSHOT" ]] && linkDest+=('--link-dest' "$BACKUP_ROOT/$LAST_SNAPSHOT")
...

rsync $OPTS $EXCLUDES "${linkDest[@]}" "$MASTER/" "$NEW_SNAPSHOT"

"${linkDest[@]}"参照が空の場合、参照は完全に消えます。それ以外の場合は、その値の参照リストに展開されます。$OPTSとがリストであれば、$EXCLUDES同じメカニズムを使用します。

おすすめ記事