2014-09-30 32 views
0

我正在努力保護bash/rsync腳本的某些輸入。總之,我試圖導航rsync'ing一些目錄,我遇到的問題是,一些目錄可能有奇怪的字符,如$符號和其他人有單引號'將輸入保護爲具有奇數字符和單引號的目錄bash

我發現如果我用""保護輸入中的變量,那麼$ABC目錄受到保護並正確處理,但帶有單引號的目錄不會。相反,如果我使用單引號保護它們,則$ABC將失敗,但帶單引號的目錄有效。

我試過以不同的方式在我的變量周圍堆疊引號和單引號,但在每種情況下都存在不同的錯誤,我無法迎合輸入流中的變量和單引號使用相同的解決方案。

下面是我的工作代碼片段:

cd $SRCDIR; find . -type d -print0 | xargs -0 -n1 -P$THREADS -I {} bash -c 'echo $TARGETDIR/"'{}'"; mkdir -p $TARGETDIR/"'{}'"; rsync -lptgoDdvXsz "'{}'"/ $TARGETDIR/"'{}'"' 

在這種配置中,它轉移有單引號(如目錄):

/data/here's my photos/ 

但不會轉移內容作者:

/data/$ABC 

如果我逆轉單引號和雙引號,我得到相反的行爲,但我努力讓這兩個工作。

我簽出了這個帖子:Problems with single quotes in a bash script但是在任何一個方向堆疊引號也沒有幫助。

回答

0

由於xargs將取代{}本身,因此不需要將它們排除在引號之外;以下是等同的,但更容易遵循。 (而且,正如伊坦指出,這是更好地讓生成的腳本接受xargs的字符串作爲參數,而不是包括腳本本身{}

cd $SRCDIR 
find . -type d -print0 | 
    xargs -0 -n1 -P$THREADS bash -c ' 
    echo "$TARGETDIR/$1" 
    mkdir -p "$TARGETDIR/$1" 
    rsync -lptgoDdvXsz "$1/" "$TARGETDIR/$1"' - 

現在,由於bash命令將獲得$TARGETDIR字面上(因爲是單引號內),只要確保變量是出口到bash命令的環境與冗餘的前瞻性

TARGETDIR=$TARGETDIR xargs -0 -n1 ... 

這將在環境的TARGETDIR值3210將運行,這是由每個最終調用bash繼承。

而我的通常建議是:如果您使用的是bash 4,請跳過find,只使用利用globstar操作符的for循環。這樣會更有效率,因爲您不需要爲每個目錄啓動bash的新實例,並且shell的擴展**/*的效率不應該比使用find的效率低得多。

shopt -s globstar nullglob 
for d in "$SRCDIR"/**/*/; do 
    echo "$TARGETDIR/$d" 
    mkdir -p "$TARGETDIR/$d" 
    rsync -lptgoDdvXsz "$d/" "$TARGETDIR/$d" 
done 
+2

文件名中的雙引號會將它們吹起來,因爲它們直接注入到腳本中(這是您對「{}」的註釋)。這就是爲什麼您將文件名作爲參數傳遞給腳本並在腳本中使用'$ 0'或'$ 1'的原因。 – 2014-09-30 17:53:01

+0

嘎,你說得對。我需要停止回答涉及'bash -c'的問題:) – chepner 2014-09-30 17:54:13

+0

我通常不會使用'xargs',但我想我已經編輯了正確傳遞文件名的答案。 – chepner 2014-09-30 17:59:14

0

試試這個:

escapedFilename=$(printf '%q' "$filename") 
0

這不是保護的方法,但你可以做一個'的存在取決於這兩個命令。這可能不像上面那樣好,但邏輯非常簡單。

if [[ $ABC == *'* ]] 
then 
    do the command for if there is a '; 
else 
    do the command if there is not a '; 
fi 
相關問題