Fehler beim Ausführen des Find-Befehls mit Variable

Fehler beim Ausführen des Find-Befehls mit Variable

Ich habe einen findBefehl zum Kopieren einiger Quelldateien geschrieben:

find ./lib ./tools -type f -regex '.*\.\(cpp\|c\|h\)$' -exec cp --parents \{\} /tmp/potato \; -print

Das funktioniert gut, aber ich möchte das Trailing -printoptional hinzufügen, also mache ich so etwas:

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}
}

Es tritt jedoch ein Fehler auf:

find: missing argument to `-exec'

Ich weiß nicht, warum es fehlschlägt und wäre für jeden Rat dankbar. Vielen Dank im Voraus!

Antwort1

Verwenden Sie entweder ein Array und führen Sie es als Argumente für einen einfachen Befehl aus.

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[@]}"
}

Oder einen String und werte ihn als Shellcode aus:

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"
}

Beachten Sie, dass im obigen Code darauf geachtet werden muss, dass ${args[destdir]}zum Zeitpunkt der Zuweisung nicht erweitert wird, da sonst sein Inhalt evalzur Auswertung als Shell-Code übergeben würde! Die sichere Verwendung kann schwierig sein eval. Ich würde den Array-Ansatz wählen, insbesondere wenn Sie bereits assoziative Arrays verwenden.

In Ihrem Ansatz haben Sie den Operator split+glob auf Ihren String angewendet, um die Argumente eines einfachen Befehls zu erstellen. Das hat nicht funktioniert, weil das letzte Argument to statt just findwar (und Sie hätten auch Probleme mit den wörtlichen Anführungszeichen, die an übergeben wurden ). Sie könnten den Operator split+glob wie folgt verwenden:\;;find

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
}

Das bedeutet aber, dass es nicht funktioniert, wenn ${args[destdir]}es Leerzeichen enthält. Sie können diese Leerzeichen immer durch ein Zeichen ersetzen, das weniger wahrscheinlich in ${args[destdir]}Zeilenumbrüchen vorkommt :.

verwandte Informationen