環境変数でコマンド引数を正しくエスケープする方法

環境変数でコマンド引数を正しくエスケープする方法

find両方のコマンドの出力をマージして、次の演算子にパイプしようとします。両方の実行に渡されるパラメータはfind非常に似ているので、そのままにしたいと思います。

FIND_CMD_ARGS="-type f \( -iname \*.m -o -iname \*.swift \) -print0"
CMD_OUTPUT=`{ find $PROJECT_PATH -not -path '*/Pods/*' $FIND_CMD_ARGS; find . -path '*/Pods/MyProject*/*' $FIND_CMD_ARGS }`

何らかの理由でこれは機能しません。これが私が得た結果です。

find: illegal option -- n
usage: find [-H | -L | -P] [-EXdsx] [-f path] path ... [expression]
       find [-H | -L | -P] [-EXdsx] -f path [path ...] [expression]
find: -type f \( -iname \*.m -o -iname \*.swift \) -print0: unknown primary or operator

考えるargs問題は環境変数でエスケープを実行する方法に関連していますが、FIND_CMD_ARGS正しい方法がわかりません。

どんなアイデアがありますか?ありがとうございます!

ベストアンサー1

変数に複数のパラメータを保存するには、配列を使用してください。

find_args=(-type f \( -iname \*.m -o -iname \*.swift \) -print)
cmd_output=$(
  find "$PROJECT_PATH" ! -path '*/Pods/*' "${find_args[@]}"
  find . -path '*/Pods/MyProject*/*' "${find_args[@]}"
)

私も

  • 変数拡張の周りに欠落している引用符を追加しました。
  • 変数名を小文字に変更します。環境変数ではないようです(とにかく、今は配列なので環境にエクスポートできません)。
  • 非標準を-not標準に変更します!-iname別の非標準述部です)。
  • $(...)廃止予定の古い形式ではなく、コマンド置換形式を使用してください`...`
  • NULバイトを保存できない-print0変数に変更してください。-printbash

別のアプローチは、関数を宣言することです。

myfind() {
  find "$@" -type f \( -iname \*.m -o -iname \*.swift \) -print
}
cmd_output=$(
  myfind "$PROJECT_PATH" ! -path '*/Pods/*'
  myfind . -path '*/Pods/MyProject*/*'
)

これで、この変数に対してできることはあまりありません。代わりに$cmd_output-print-print0

bash 4.4以降では、代わりに配列を使用して次のものを使用できます。

myfind() {
  find "$@" -type f \( -iname \*.m -o -iname \*.swift \) -print0
}
readarray -td '' files < <(
  myfind "$PROJECT_PATH" ! -path '*/Pods/*'
  myfind . -path '*/Pods/MyProject*/*'
)

おすすめ記事