1. ホーム
  2. バッシュ

[解決済み】xargsで複数のコマンドを実行する

2022-03-24 07:02:49

質問

cat a.txt | xargs -I % echo %

上の例では、xargsは echo % をコマンドの引数として指定します。しかし、場合によっては、引数を処理するコマンドを1つではなく、複数必要とすることがある。例えば

cat a.txt | xargs -I % {command1; command2; ... }

しかし、xargsはこの形式を受け付けない。私が知っている解決策の一つは、コマンドをラップする関数を定義することですが、それは複雑なので避けたいのです。もっといい解決策はないでしょうか?

どのように解決するのですか?

cat a.txt | xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _

...または 猫の無駄遣い :

<a.txt xargs -d $'\n' sh -c 'for arg do command1 "$arg"; command2 "$arg"; ...; done' _


細かい点を説明すると

  • の使用は "$arg" の代わりに % (がないこと(そして -I の中に xargs コマンドライン)は、セキュリティ上の理由からです。でのデータの受け渡しは sh のコマンドライン引数リストをコードに代入するのではなく、データに含まれる可能性のあるコンテンツ(例えば $(rm -rf ~) 特に悪意のある例では、コードとして実行されないようにする。

  • 同様に -d $'\n' はGNU拡張機能であり、これにより xargs は、入力ファイルの各行を個別のデータ項目として扱います。これか -0 (は、xargs がシェルのような(しかし とは言えない シェルと互換性のある) 構文解析を読み込むストリームに対して行います。(GNU xargs を持っていない場合は tr '\n' '\0' <a.txt | xargs -0 ... を使用せずに行指向の読み込みを行うには -d ).

  • _ はプレースホルダーで $0 によって追加される他のデータ値は、そのような xargs になります。 $1 などがありますが、これはたまたまデフォルトの値で for ループを繰り返し実行します。