根据 man 定义,此命令从文件中获取输入。
$ command -r FILENAME
Run Code Online (Sandbox Code Playgroud)
假设这FILENAME
是一个包含文件名列表的文件,因为它是使用ls > FILENAME
.
相反,我如何ls
直接将结果提供给命令?在我看来,这样的事情应该是可能的:
$ ls | command -r
但事实并非如此, 的输出ls
不会作为参数被挂钩。输出:
Usage: command -r FILENAME
error: -r option requires an argument
Run Code Online (Sandbox Code Playgroud)
我怎样才能获得想要的效果?
Gil*_*il' 40
这取决于命令。一些从文件中读取的命令期望该文件是一个常规文件,其大小是预先知道的,并且可以从任何位置读取并倒带。如果文件的内容是文件名列表,这不太可能:那么该命令可能会包含一个管道,它将从头到尾顺序读取。有几种方法可以通过管道将数据提供给需要文件名的命令。
许多命令将其-
视为特殊名称,这意味着从标准输入读取而不是打开文件。这是约定,不是义务。
ls | command -r -
Run Code Online (Sandbox Code Playgroud)许多 unix 变体提供/dev
了指定标准描述符的特殊文件。如果/dev/stdin
存在,打开并读取它相当于从标准输入读取;同样,/dev/fd/0
如果它存在。
ls | command -r /dev/stdin
ls | command -r /dev/fd/0
Run Code Online (Sandbox Code Playgroud)如果你的shell是ksh、bash或zsh,你可以让shell处理分配一些文件描述符的业务。这种方法的主要优点是它不依赖于标准输入,因此您可以将标准输入用于其他用途,并且您可以多次使用它。
command -r <(ls)
Run Code Online (Sandbox Code Playgroud)如果命令希望名称具有特定形式(通常是特定扩展名),您可以尝试使用符号链接来欺骗它。
ln -s /dev/fd/0 list.foo
ls | command -r list.foo
Run Code Online (Sandbox Code Playgroud)
或者您可以使用命名管道。
mkfifo list.foo
ls >list.foo &
command -r list.foo
Run Code Online (Sandbox Code Playgroud)请注意,生成文件列表ls
是有问题的,因为ls
当文件名包含不可打印的字符时,往往会破坏文件名。printf '%s\n' *
更可靠——它会在文件名中逐字打印每个字节。包含换行符的文件名仍然会引起麻烦,但如果命令需要由换行符分隔的文件名列表,则这是不可避免的。
它应该是:
ls | xargs -n 1 command -r
Run Code Online (Sandbox Code Playgroud)
编辑:对于带有空格的名称:
ls | xargs -d '\n' -n 1 command -r
Run Code Online (Sandbox Code Playgroud)