我寫了一個find
命令來複製一些原始檔:
find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} /tmp/potato \; -print
這很好用,但我還想添加-print
可選的尾隨,所以我做了這樣的事情:
function deploy_source_code {
exec_cmd="find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} ${args[destdir]} \;"
if [ "${args[verbose]}" = "true" ]; then
exec_cmd="${exec_cmd} -print"
fi
${exec_cmd}
}
但它恰好失敗並出現錯誤:
find: missing argument to `-exec'
我不知道為什麼它會失敗,我將不勝感激任何建議。先致謝!
答案1
使用陣列並將其作為簡單命令的參數執行。
deploy_source_code() {
exec_cmd=(find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$'
-exec cp --parents {} "${args[destdir]}" \;)
if [ "${args[verbose]}" = "true" ]; then
exec_cmd+=(-print)
fi
"${exec_cmd[@]}"
}
或一個字串並將其計算為 shell 程式碼:
deploy_source_code() {
exec_cmd="find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' \
-exec cp --parents {} \"\${args[destdir]}\" \;"
if [ "${args[verbose]}" = "true" ]; then
exec_cmd+=" -print"
fi
eval "$exec_cmd"
}
請注意,在上面的程式碼中,重要的是要確保${args[destdir]}
在賦值時不會展開,否則它的內容將傳遞到eval
作為 shell 程式碼進行計算!它可能很難eval
安全地使用,我會使用陣列方法,特別是考慮到您已經在使用關聯數組。
在您的方法中,您在字串上使用 split+glob 運算子來建立簡單指令的參數。這不起作用,因為最後一個參數find
is\;
而不是 just ;
(而且您還會遇到傳遞給 的文字引號字元的問題find
)。您可以使用 split+glob 運算子:
deploy_source_code() {
exec_cmd="find ./lib ./tools -type f -regex .*\.\(cpp\|c\|h\)$ \
-exec cp --parents {} ${args[destdir]} ;"
if [ "${args[verbose]}" = "true" ]; then
exec_cmd+=" -print"
fi
IFS=" " # split on space
set -f # disable glob
$exec_cmd # invoke the split+glob operator
}
${args[destdir]}
但這意味著如果包含空格字元它將不起作用。您始終可以將這些空格替換為不太可能出現在${args[destdir]}
like:
或換行符中的字元。