使用變數執行 find 指令時出錯

使用變數執行 find 指令時出錯

我寫了一個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 運算子來建立簡單指令的參數。這不起作用,因為最後一個參數findis\;而不是 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:或換行符中的字元。

相關內容