変数を使用して 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[@]}"
}

または、文字列を使用してそれをシェルコードとして評価します。

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シェルコードとして評価されるように渡されます。安全に使用するのが難しい場合がありますeval。特に、すでに連想配列を使用していることを考慮すると、配列アプローチを使用します。

この方法では、文字列に Split+glob 演算子を使用して単純なコマンドの引数を作成します。最後の引数がjustの代わりにfindisなので、これはうまくいきません(そしてに渡されたリテラル引用符にも問題があります)。分割+グローブ演算子を使用できます。\;;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
}

${args[destdir]}ただし、これは空白文字が含まれていると機能しないことを意味します。いつでも、これらのスペースを類似または改行に${args[destdir]}現れる:可能性の低い文字に置き換えることができます。

おすすめ記事