なぜxargsが必要なのですか?


25

「notes.txt」という名前のファイルを除くディレクトリ内のすべてのファイルを削除するとします。これをパイプラインで行いls | grep -v "notes.txt" | xargs rmます。2番目のパイプの出力がrmが使用すべき入力である場合、なぜxargsが必要なのですか?

比較のために、パイプラインは、echo "#include <knowledge.h>" | cat > foo.cxargsを使用せずにエコーされたテキストをファイルに挿入します。これら2つのパイプラインの違いは何ですか?


3
ls | grep -v "notes.txt" | xargs rmを除くすべてを削除するために使用しないでください。notes.txt一般的には、出力を解析しないでくださいls。たとえば、単一のファイルにスペースが含まれていると、コマンドが壊れます。より安全な方法はrm !(notes.txt)、Bash(shopt -s extglobセットあり)、またはrm ^notes.txtZsh(ありEXTENDED_GLOB)などです
。– slhck

スペースを避けるためfind . -maxdepth 1 -mindepth 1 -print0 | xargs -0に、代わりに行うことができますls | xargs:-)
flob 14年

回答:


35

STDINと引数の2つの非常に異なる種類の入力を混同しています。引数は、コマンドの開始時にコマンドに提供される文字列のリストです。通常は、コマンド名の後に指定します(例:echo these are some argumentsまたはrm file1 file2)。一方、STDINは、コマンドが(オプションで)開始後に読み取ることができるバイトストリーム(テキストではない場合もあります)です。以下にいくつかの例を示します(cat引数またはSTDINのいずれかを取ることができますが、異なることをします)。

echo file1 file2 | cat    # Prints "file1 file2", since that's the stream of
                          # bytes that echo passed to cat's STDIN
cat file1 file2    # Prints the CONTENTS of file1 and file2
echo file1 file2 | rm    # Prints an error message, since rm expects arguments
                         # and doesn't read from STDIN

xargs STDINスタイルの入力を引数に変換すると考えることができます。

echo file1 file2 | cat    # Prints "file1 file2"
echo file1 file2 | xargs cat    # Prints the CONTENTS of file1 and file2

echo 実際には多かれ少なかれ反対を行います:引数をSTDOUT(他のコマンドのSTDINにパイプすることができます)に変換します:

echo file1 file2 | echo    # Prints a blank line, since echo doesn't read from STDIN
echo file1 file2 | xargs echo    # Prints "file1 file2" -- the first echo turns
                                 # them from arguments into STDOUT, xargs turns
                                 # them back into arguments, and the second echo
                                 # turns them back into STDOUT
echo file1 file2 | xargs echo | xargs echo | xargs echo | xargs echo    # Similar,
                                 # except that it converts back and forth between
                                 # args and STDOUT several times before finally
                                 # printing "file1 file2" to STDOUT.

9

cat入力を受け取りますがSTDIN、受け取りrmません。このようなコマンドの場合、行xargsごとに繰り返しSTDIN、コマンドラインパラメーターを使用してコマンドを実行する必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.