
コマンド引数変数を rsync で動作させるのに本当に苦労しています。私が見ている動作は、スクリプトからの次のエラーです:
rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: unexplained error (code 255) at io.c(601) [sender=3.0.7]
ただし、スクリプトは実行するコマンドをエコー経由で出力し、まったく同じコマンドをターミナルにコピーして貼り付けると (または、スクリプトの最初の行として exit を付けて戻すと)、正常に動作します。
この rsync を実行するスクリプト コード (この場合 check_flags は空です):
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- \"${backup_dir}\" \"admin@nas-1:${backup_basename}/\")
echo "CMD to run: rsync ${rsync_cmd[@]}"
rsync ${rsync_cmd[@]}
出力:
CMD to run: rsync -rWltpgoDvdHP --delete-before -- "/share/CACHEDEV1_DATA/veeam_backup_daily/Daily backup _@1am__1" "admin@nas-1:/share/CACHEDEV1_DATA/veeam_backup_daily/"
配列を使用するとこの問題が解決するはずだとオンラインで読みましたが、この場合はうまくいきませんでした。これは簡単に解決できると確信していますが、気が狂いそうです。
答え1
シェルは変数を置換する前に引用符を解析するので、変数の値に引用符を含めても期待どおりには動作しません ( はecho
この区別を表示しないため、非常に誤解を招きます)。配列を定義するときにエスケープされていない引用符を使用し (配列値の一部ではなく、配列要素を囲む区切り文字として解析されます)、配列への参照を二重引用符で囲みます (配列内の値が単語分割されたりワイルドカードで展開されたりしないようにするため)。また、echo
コマンドを に置き換えるとprintf
、何が起こるかがより正確に表示されます。
rsync_cmd=(${check_flags} -rWltpgoDvdHP --delete-before -- "${backup_dir}" "admin@nas-1:${backup_basename}/")
printf "%q " CMD to run: rsync "${rsync_cmd[@]}"
printf "\n"
rsync "${rsync_cmd[@]}"
printf
期待どおりに表示されない場合があることに注意してください。同等は実行されるコマンドの表現ですが、各引数には多くの異なる同等の表現があり、最初に入力された方法ではなく、設定に基づいて 1 つが選択されます。ちなみに、を使用してset -x
このようなものをデバッグすることもできますが、( と同様にprintf "%q "
) 予想とは異なる表現が使用される可能性があります。