为什么需要xargs?


25

假设我要删除目录中除名为“ notes.txt”的文件以外的所有文件。我将使用管道来执行此操作ls | grep -v "notes.txt" | xargs rm。如果第二个管道的输出是rm应该使用的输入,为什么我需要xargs?

为了进行比较,管道echo "#include <knowledge.h>" | cat > foo.c将回显的文本插入文件中,而不使用xargs。这两条管道有什么区别?


3
ls | grep -v "notes.txt" | xargs rm除了notes.txt或通常从不解析lsoutput之外,您不应使用它来删除所有内容。例如,如果单个文件包含空格,则命令将中断。更安全的方法是rm !(notes.txt)使用Bash(带有shopt -s extglobset)或rm ^notes.txtZsh(带有EXTENDED_GLOB)等
。– slhck

为了避免空格,您可以find . -maxdepth 1 -mindepth 1 -print0 | xargs -0代替ls | xargs:-)
絮絮

Answers:


35

您会混淆两种非常不同的输入:STDIN和参数。参数是在启动时提供给命令的字符串的列表,通常通过在命令名称之后指定它们(例如echo these are some argumentsrm 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需要输入从STDINrm没有。对于此类命令,您需要逐行xargs迭代STDIN并使用命令行参数执行命令。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.