Bash
發現目錄中的空間無法按預期工作
我有一個腳本呼叫這個
find "/mnt/Data/Shared/$1" -type d -exec bash -c 'fixperm "'${1}'" "fd" "$0"' {} \;
$1 是一個目錄,當名稱不包含空格時它可以工作,當有空格時它會失敗並返回錯誤。使用“00_Office 測試”進行測試
Test" "fd" "$0": -c: line 0: unexpected EOF while looking for matching `"' Test" "fd" "$0": -c: line 1: syntax error: unexpected end of file
我認為這可能是因為路徑在空格之前缺少 \ 但這並不能解決問題。我確定我在這裡遺漏了一些微不足道的東西。
那是因為您使用的是未引用的
${1}
.報價
解決報價問題可能會變得相當複雜。
替換
'${1}'
為'"${1}"'
似乎有幫助。比較:
$ set -- "ab cd"; bash -c 'printf "<%s> " '${1}' "fd" "$0"' <ab>
和:
$ set -- "ab cd"; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"' <ab> <cd> <fd> <bash>
但是,shell“引號刪除”仍然應用於變數值。
作為一種解決方法,您可以使用
'"${1@Q}"'
$ set -- 'a"b c"d'; bash -c 'printf "<%s> " '"${1}"' "fd" "$0"'; echo <ab cd> <fd> <bash> # quotes got lost. $ set -- 'a"bc"d'; bash -c 'printf "<%s> " '"${1@Q}"' "fd" "$0"'; echo <a"b c"d> <fd> <bash> # correct quotes.
但是,這仍然不適用於您的命令具有的兩個 shell 暴露循環(首先是
find
命令,然後是bash -c
命令):$ mkdir 'a"bc"d' 'a"b c"d' 'a"bcd' $ set -- 'a"bc"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} > <fixperm> <abcd> <fd> <./a"b c"d> $ set -- 'a"b c"d'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} > <fixperm> <ab> <cd> <fd> <./a"b c"d> $ set -- 'a"bcd'; find "./$1" -type d -exec bash -c 'printf "<%s> " fixperm "'"${1}"'" "fd" "$0"' {} \; ./a"bcd: -c: line 0: unexpected EOF while looking for matching `"' ./a"bcd: -c: line 1: syntax error: unexpected end of file
正確的
$1
但是,真正發生的是,您呼叫的腳本的參數與$1
被呼叫的 shell 的含義之間似乎存在混淆bash -c
該行:
find "/mnt/Data/Shared/$1" -type d -exec bash -c ' fixperm "'"${1}"'" "fd" "$0"' {} \;
應該讀:
find "/mnt/Data/Shared/$1" -type d -exec bash -c ' fixperm "$1" "fd" "$2"' bash-shell "$1" {} \;
這使得報價直接且更加穩健。
簡單的
如果腳本中沒有循環或其他復雜的函式可以執行
bash -c
,幾乎所有的引用都可以去掉並寫成:dir="/mnt/Data/Shared" find "$dir/$1" -type d -exec fixperm "$1" fd {} \;
那是因為它
${1}
出現在單引號之外,即它find
甚至在看到它之前就被shell 擴展和分詞。StackExchange 上突出顯示的語法清楚地表明了這一點。使用雙引號來防止分詞。此外,通過呼叫
bash -c
,您需要自己處理引用,但如果文件名包含雙引號,它可能會中斷。不要使用它,直接傳遞參數:find "/mnt/Data/Shared/$1" -type d -exec fixperm "$1" fd {} \;