「xargs」とコマンド置換の違いは?


14

多くの場合、の代わりにコマンド置換を使用しますxargs。たとえばrm $(ls)、次と同じですls | xargs rm

それらの違いは何ですか?

違いの1つは、コマンド置換がxargs現在のシェルで実行されているときにサブシェルで実行されることですが、よくわかりません。

違いをリストしてください。

回答:


9

1つの違いは、パイプの代わりにコマンド置換を使用する場合、渡されるデータのサイズはコマンドバッファーのサイズによって制限されるため、警告なしで切り捨てられる場合があることです。これは、次のコマンドに渡される前に、コマンド出力全体を生成し、メモリに保存する必要があることを意味します。そのため、大きな出力では、必要以上のメモリを使用できます。

最初の方法の別の問題は、出力が空白で分割されるため、スペースが含まれるファイル名を処理できないことです。xargsまた、空白の問題の影響も受けますが、使用する区切り文字を変更することで修正できます。ちなみにファイル名を適切に処理するには、2番目の例で区切り文字としてヌルバイトを使用する必要があります。

3番目の問題は、グロブが展開されるため、ファイルの名前にアスタリスクまたは疑問符が含まれている場合、予期しない結果が生じることです。

この問題については、http//mywiki.wooledge.org/ParsingLsで素晴らしい議論を見つけることができます

正しい構文は

echo rm *

またはxargsを使用する必要がある場合、

find . -maxdepth 1 -print0 | xargs -0 echo rm

echo出力が正しいように見えたら削除します。


1
@Sinoosh:xargsパイプが原因でサブシェルでも実行されますが、有効shopt -s lastpipeにしない限り、現在のシェルで実行されます。この場合、変数を変更していないので、サブシェルで実行することは問題ではないと思います。
user000001

1
@Sinoosh:引数を1つずつ渡すには-l、などのフラグを使用できますfind . -maxdepth 1 -print0 | xargs -0 -l rm。2番目の質問では、lsはnullビュートで出力を分割しないためls、with は使用できませんxargs -0が、改行(ファイル名BTWで有効です)
-user000001

1
@Sinoosh:最初の段落ではなく、2番目の段落:-0オプションなしのxargs は空白の問題に悩まされています。
user000001

1
読み取りman xargsではechoなく、テストに使用しますrmxargsシェルの制限を超えることができます(一部のバッファは65Kに制限されていますが、ファイル名のリストは制限されていません)。
ワルチネーター

1
@Sinoosh:便利なリファレンスはありませんが、入力することができxargs --show-limits、システムに設定されている制限が表示されます
user000001
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.