2016-08-17 68 views
0

我正在使用bash腳本來使用rsync同步Web文件夾。我使用的文件夾和文件要排除的陣列,和我在逃避這些項目的排除列表的問題...在bash腳本中引用rsync的排除問題

我排除被定義像這樣列表...

SYNC_EXCLUSIONS=(
    '/exclude_folder_1' 
    '/exclude_folder_2' 
    '.git*' 
    '.svn' 
) 

然後,我建我的排斥字符串是這樣的...

exclusions=''; 
for e in "${SYNC_EXCLUSIONS[@]}" 
do 
    exclusions+=" --exclude='$e'"; 
done 

於是最後我執行我的rsync ...

rsync --recursive --delete $exclusions "$DEPLOYMENT_WORK_DIR/" "$DEPLOYMENT_ROOT/" 

如果我回應命令,它看起來很完美,如果我在提示中複製並執行它,它就能正常工作。但是,從腳本運行時,排除將被忽略。

我已經想通了,如果我周圍的每個排除的項目去掉單引號,像這樣將工作...

exclusions+=" --exclude=$e"; 

我寧願不要做,雖然,以防萬一我需要排除空格或特殊字符的文件夾。

有沒有某種方式可以讓我從腳本中工作,同時在排除的項目周圍保留引號?我嘗試了各種各樣的引號和反斜槓等組合,但我沒有嘗試過。

+1

請參見[BashFAQ#50](http://mywiki.wooledge.org/BashFAQ/050) –

+0

順便說一句,對你自己的變量使用全大寫的名字是不好的形式。請參見[POSIX關於環境變量名稱的指導原則](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html)(第4段),指定shell和系統使用具有全大寫名稱的變量,並且具有其他名稱的變量可以被應用程序使用而不會發生衝突;因爲shell變量共享一個名稱空間(使用環境變量的名稱設置shell變量將覆蓋後者),這些約定也適用於shell變量。 –

+0

謝謝,我沒有意識到這一點。這是我在其他各種語言中使用的一種約定,用於表示某些內容旨在保持不變。我沒有意識到在bash中這不是好習慣。我會改變我的代碼。 – user1751825

回答

2

您根本無法爲此創建字符串 - 請參閱BashFAQ #50以瞭解關於原因的廣泛討論。建立一個數組。

exclusions=() 
for e in "${SYNC_EXCLUSIONS[@]}"; do 
    exclusions+=(--exclude="$e") 
done 

rsync --recursive --delete "${exclusions[@]}" "$DEPLOYMENT_WORK_DIR/" "$DEPLOYMENT_ROOT/" 

...好,不能建立一個串上,除非你要與eval來執行它。這樣做的方式,不容易殼注入漏洞照顧,但是:

printf -v exclusions_str '--exclude=%q ' "${SYNC_EXCLUSIONS[@]}" 
printf -v rsync_cmd 'rsync --recursive --delete %s %q %q' \ 
    "$exclusions_str" "$DEPLOYMENT_WORK_DIR/" "$DEPLOYMENT_ROOT/" 
eval "$rsync_cmd" 
+0

謝謝,這工作完美。 – user1751825

+1

您可以通過字符串替換的魔術創建不帶循環的'exclusions'數組:'exclusions =(「$ {SYNC_EXCLUSIONS [@] /#/ - exclude =}」)'。這擴大了'SYNC_EXCLUSIONS',但是在每個元素中用'--exclude ='替換'字符串的開始(「#」)。 –