Mar*_*nco 2 shell pipe io-redirection background-process
这是我的解释:
strings *.bin > bin.txt | sort -n bin.txt > logs1.txt
这给了我logs1.txt
,但它有 621 KB。
strings *.bin > bin.txt & sort -n bin.txt > logs1.txt
这给了我logs1.txt
,但它有 0 KB。
strings *.bin > bin.txt
sort -n bin.txt > logs2.txt
logs2.txt
这些命令提供586,853 KB 大小的文件。
请注意,bin.txt
大小为 586,853 KB,这意味着仅运行 3 个选项即可获得与 相同的大小bin.txt
,我想知道原因。
此答案中的一些详细信息假设用户使用zsh
. zsh
由于其MULTIOS
功能不同,外壳的细节略有不同。
strings *.bin > bin.txt | sort -n bin.txt > logs1.txt
这将运行strings *.bin
并将结果重定向到bin.txt
. 启动的同时strings
,sort
启动并对文件进行排序bin.txt
。除了允许两个命令同时运行之外,管道在此管道中没有任何功能。
通常,管道用于将左侧命令的标准输出传输到右侧命令的标准输入,但由于这两个命令都是从文件读取,因此从不使用管道。
由于 和strings
都是sort
同时启动的,因此可能会在完成整个文件的写入之前sort
找到文件的结尾。如果有的话,最终会读取多少数据是相当随机的。bin.txt
strings
sort
正确使用管道看起来像
strings -- *.bin | sort -n > logs1.txt
Run Code Online (Sandbox Code Playgroud)
在这里,strings
直接写入到输入sort
而不是文件,并sort
从输出读取strings
而不是从文件读取。
如果管道的左侧不能足够快地产生数据,则管道的右侧将被暂时阻塞;如果管道的右侧不能足够快地消耗数据,则管道的左侧将被暂时阻塞。这样,两个实用程序就会同步,并且保证您sort
将读取 的完整输出strings
。
strings *.bin > bin.txt & sort -n bin.txt > logs1.txt
这与上一个命令存在相同的问题,因为两者strings
都是sort
同时启动的。该程序在后台&
启动,然后立即启动。两个实用程序彼此独立地写入或读取,并且有机会决定在到达文件末尾之前写入多少文件。strings
sort
bin.txt
sort
strings *.bin > bin.txt
其次是sort -n bin.txt > logs2.txt
。
strings
在这里,您可以通过允许在对中间文件的内容bin.txt
进行排序之前完成中间文件的写入来手动同步这两个实用程序sort
。没有问题,并且保证您sort
能够strings
从文件中读取完整的输出。
摘要:前两个命令不同步strings
和sort
实用程序。by 的写入strings
与 的读取无关sort
。这意味着可以在完成写入所有数据sort
之前找到中间文件的末尾。strings
反过来,这意味着您可能会得到不完整的最终结果。您的不完整结果将包含的数据量取决于机会。
这两个实用程序同时启动的事实也意味着,sort
甚至可能在 shell 有时间截断文件并启动之前将预先存在的文件读bin.txt
到底strings
。
解决方案:首先将所有数据写入中间文件,然后从中读取,如第三个示例所示。或者,允许两个实用程序使用管道直接在它们之间通信数据,如我上面的建议所示:
strings -- *.bin | sort -n > logs1.txt
Run Code Online (Sandbox Code Playgroud)
或者保留未排序输出的副本strings
以供将来参考:
strings -- *.bin | tee bin.txt | sort -n > logs1.txt
Run Code Online (Sandbox Code Playgroud)
有关 U&L 的更多相关阅读: