Shell

幫助 Shell 腳本將變數傳遞給 rsync

  • January 20, 2014

我正在嘗試為 rsync 創建一個簡單的包裝器 shell 腳本。當我將文件名發送到我的腳本時,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]

問題是您需要引用文件名,但是您不能使用字元串來完成所有這些操作,因為它會將所有文件名作為一個長字元串傳遞給 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[@]}" .

採用:

# 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.

引用自:https://unix.stackexchange.com/questions/109729