在命令选项中使用从管道读取的数据而不是从文件读取的数据

在命令选项中使用从管道读取的数据而不是从文件读取的数据

根据 man 定义,此命令从文件获取输入。

$ command -r FILENAME

假设这FILENAME是一个包含文件名列表的文件,因为它是使用ls > FILENAME.

相反,我如何直接向命令提供结果ls?在我看来,这样的事情应该是可能的:

$ ls | command -r

但事实并非如此, 的输出ls不会作为参数被挂钩。输出:

Usage: command -r FILENAME
error: -r option requires an argument

怎样才能达到想要的效果呢?

答案1

这取决于命令。一些从文件读取的命令期望该文件是常规文件,其大小预先已知,并且可以从任何位置读取并倒回。如果文件的内容是文件名列表,则这种情况不太可能发生:那么该命令可能会包含一个管道它只会从头到尾按顺序读取。有多种方法可以通过管道将数据提供给需要文件名的命令。

  • 许多命令将其-视为特殊名称,意思是从中读取标准输入而不是打开文件。这是约定,而不是义务。

    ls | command -r -
    
  • /dev许多 UNIX 变体提供了指定标准描述符的特殊文件。如果/dev/stdin存在,则打开它并从中读取,相当于从标准输入中读取;/dev/fd/0如果存在的话同样如此。

    ls | command -r /dev/stdin
    ls | command -r /dev/fd/0
    
  • 如果您的 shell 是 ksh、bash 或 zsh,您可以让 shell 处理分配某些文件描述符的业务。此方法的主要优点是它不依赖于标准输入,因此您可以将标准输入用于其他用途,并且可以多次使用它。

    command -r <(ls)
    
  • 如果命令期望名称具有特定的形式(通常是特定的扩展名),您可以尝试使用符号链接来欺骗它。

    ln -s /dev/fd/0 list.foo
    ls | command -r list.foo
    

    或者您可以使用命名管道。

    mkfifo list.foo
    ls >list.foo &
    command -r list.foo
    

注意生成文件列表ls是有问题的因为ls当文件名包含不可打印的字符时,它往往会破坏文件名。printf '%s\n' *更可靠 — 它会逐字打印文件名中的每个字节。包含换行符的文件名仍然会引起麻烦,但如果命令需要用换行符分隔的文件名列表,这是不可避免的。

答案2

它应该是:

ls | xargs -n 1 command -r

编辑:对于带有空格的名称:

ls | xargs -d '\n' -n 1 command -r

答案3

许多命令接受-“文件名”,这意味着“使用标准输入”,但这种约定远非通用。阅读手册页。

答案4

这应该适合您的目的:ls | command -r /dev/stdin

相关内容