Case ステートメントで xargs を使用する

Case ステートメントで xargs を使用する

$()(中に入れることができない)長いコマンドの出力をCase文にパイプしたいので、xargs次のように使用します。

echo "this" | xargs -I{} case {} in; this) echo "is a test";; esac

動作しません。エラーが発生します。

zsh: parse error near `)'

そして、以下は問題なく実行されます

case "this" in; this) echo "is a test";; esac

どうすれば解決できますか?

答え1

case...in...esacsh言語に似た構成なので(xargsシェル構成ではなくシェルとは別のコマンド)、そのためにシェルを呼び出す必要があります。

echo this | xargs -I'{}' sh -c '
  case $1 in
    (this) echo "is a test";;
  esac' sh '{}'

{}いずれの場合も(引用符とスペースの後にxargs最終的に各行に展開される内容)がないことを確認する必要があります。パスワードインラインスクリプトへの引数sh(またはshだけでなく、すべてのインタプリタへのコード引数)、それ以外の場合はコード注入の脆弱性になります。

代わりに、ここでは{}インラインスクリプト(スクリプトを使用して検索)にパラメータとして渡されるため、$1シェルコードとして解釈することはできません。

case現在(ここ)シェルzshでコマンド出力のすべての行に対して設定を実行するには(xargs -I'{}'ところで、バックスラッシュ、一重引用符、二重引用符を含まず、空白で始まらない行のみ)、これを行うことができます。

while IFS= read <&3 -r line; do
  case $line in
    (this) ...;;
  esac 3<&-
done 3< <(a-command)

または

for line (${(f)"$(a-command)"}) case $line in
  (this) ...;;
esac

(その人は空行をスキップします)。

答え2

case私はもともとドアが複数行にわたって構成されていたので問題があると思いました。次のようにさらに成功することができます。

yourcommand | while read LINE ; do
  case "$LINE" in; this) echo "is a test";; esac
done

関連情報