Cha*_*ert 9 command-line shell io-redirection
我有这个命令:
cat somefile >file1 >file2
Run Code Online (Sandbox Code Playgroud)
执行此命令后,我无法弄清楚为什么其中file1
没有任何内容。它应该具有第一个文件 ( somefile
)的输出,但其中没有任何内容。
你能向我解释为什么它不从 复制或写入我的输出somefile
吗?(file2
包含我的输出,但不file1
包含任何内容)
dar*_*nir 16
我认为您认为 shell 重定向的工作方式与其实际工作方式有所不同。
您不能多次重定向 shell 的输出并期望它被重定向到您指定的所有位置。相反,它只会被重定向到最后一个位置,在您的情况下是file2
. Chaos 的回答为此类 I/O 重定向的工作原理提供了一个不错的解释。
你真正想做的是:
$ cat example.txt | tee file1 > file2
Run Code Online (Sandbox Code Playgroud)
tee
是一个从标准输入读取并写入多个文件描述符的程序。其中之一始终是标准输出。因此,我们使用tee
将输出写入file1
,然后将其标准输出重定向到file2
.
此外,根据评论中的建议,这是做您正在寻找的更好的方法:
$ tee file1 > file2 < example.txt
Run Code Online (Sandbox Code Playgroud)
这种方法的优点是它重定向stdin
而不是尝试通过管道读取。这意味着 shell 现在需要少生成一个进程。它还消除了所谓的“无用的使用 cat”。
你所做的,被称为I/O-Redirection。>file
将标准输出 (stdout) 重定向到给定的file
. 在你的情况下,你做了 2 次。shell 不会多次处理相同输出的重定向。
在这种情况下:
cat somefile >file1 >file2
Run Code Online (Sandbox Code Playgroud)
shell 在执行命令 ( cat somefile
)之前处理重定向。这意味着将>
文件截断为零长度,因为您覆盖了文件内容。该文件必须为空,shell 才能执行命令。这是通过两个>
重定向完成的。
现在,第二个 ( >file2
) 覆盖了第一个 ( >file1
),因为外壳程序按照出现的顺序处理重定向。因此,最后一种是将有效使用的一种。的输出cat somefile
将因此被重定向到file2
与file1
将被截断为长度为零。
可以tee
像这样将标准输出重定向到多个进程/文件:
cat somefile | tee file1 file2 file3 fileX
Run Code Online (Sandbox Code Playgroud)
这会将内容打印到标准输出和作为参数给出的所有文件。