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の代わりにfind
isなので、これはうまくいきません(そしてに渡されたリテラル引用符にも問題があります)。分割+グローブ演算子を使用できます。\;
;
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]}
現れる:
可能性の低い文字に置き換えることができます。