Shell
幫助 Shell 腳本將變數傳遞給 rsync
我正在嘗試為 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
.