xargsが一部のコマンドでは機能しますが、他のコマンドでは機能しないのはなぜですか?

xargsが一部のコマンドでは機能しますが、他のコマンドでは機能しないのはなぜですか?

このコマンドを実行すると動作します。

find . -type f -print0 | xargs md5sum

これにより、各ファイルのmd5sumが印刷されます。

しかし、他のコマンドでは、すべてのファイルを単一のコマンド呼び出しに渡すようです。たとえば、この問題があるようですprintf。次の警告が表示echoされますprintf

printf: warning: ignoring excess arguments, starting with ...

echoを使用すると、たとえば、次のコマンドがある場合は1行だけ印刷されます。

find . -type f -print0 | xargs -r0 echo GOT

見つかったすべてのファイルと同じ行に「GOT」が一度だけ印刷されたことがわかります。

echoも組み込まれているからだと思いましたが、/bin/echoを明示的に実行すると同じ動作が発生します。

ちなみに、makeコマンドでも次のような問題が発生しました。

$ echo "a b c" | xargs echo GOT
GOT a b c

変える:

GOT a
GOT b
GOT c

私は何が間違っていましたか?まず、コマンドにプレフィックスを付けてデバッグするのはとても役に立ちましたが、echoそうすることもできません。

編集:コメントで述べたように、実際にはその-execオプションは利用できませんfind。実際には、ソートを含むかなり長いパイプラインがありますが、これは無関係な詳細であるようで、私が得ることができないという事実とは何の関係もありません。より簡単なパイプライン作業。

ベストアンサー1

標準入力から取得されたすべての内容が追加され、いくつかの区切り文字で区切られたxargs command-argコマンドの単一インスタンスを実行すると考えることができます(デフォルトは例で使用した空白またはNULバイトです)。command-argたとえば、

echo 1 2 3 | xargs something

実行できますsomething 1 2 3。または質問に投稿した例を使用して:

echo "a b c" | xargs echo GOT

走るecho GOT a b c

標準入力から取得した各引数 xargs を使用して新しい command-arg インスタンスを生成するには、-n1 オプションを使用できます。

$ echo "a b c" | xargs -n1 echo GOT
GOT a
GOT b
GOT c

もちろん、いくつかのコマンドは複数の引数を受け入れないので、常に使用する必要があります-n1

xargsを使用する利点は、新しいプロセスを作成するのが高価な作業であるため、複数の引数を使用して単一のプロセスを実行する方が高速です。この回答で行ったいくつかのベンチマークを確認してください。 https://unix.stackexchange.com/a/536023/72304

おすすめ記事