为什么使用“|”或“&”提供不同大小的结果文件?

为什么使用“|”或“&”提供不同大小的结果文件?

这是我的解释:

  1. strings *.bin > bin.txt | sort -n bin.txt > logs1.txt

    这给了我logs1.txt,但它有 621 KB。

  2. strings *.bin > bin.txt & sort -n bin.txt > logs1.txt

    这给了我logs1.txt,但它有 0 KB。

  3. strings *.bin > bin.txt
    sort -n bin.txt > logs2.txt

    这些命令提供 586,853 KB 的文件logs2.txt

请注意,bin.txt大小为 586,853 KB,这意味着仅运行 3 个选项即可获得与 相同的大小bin.txt,我想知道原因。

答案1

此答案中的一些详细信息假设用户使用zsh.zsh由于以下原因,外壳的细节略有不同它的MULTIOS特点

  1. strings *.bin > bin.txt | sort -n bin.txt > logs1.txt

    这将运行strings *.bin并将结果重定向到bin.txt.启动的同时stringssort启动并对文件进行排序bin.txt。除了允许两个命令同时运行之外,管道在此管道中没有任何功能。

    通常,管道用于将左侧命令的标准输出传输到右侧命令的标准输入,但由于这两个命令都是从文件读取,因此从不使用管道。

    由于stringssort都是同时启动的,因此可能会在完成整个文件的写入之前sort找到文件的结尾。如果有的话,最终会读取多少数据是相当随机的。bin.txtstringssort

    正确使用管道看起来像

    strings -- *.bin | sort -n > logs1.txt
    

    在这里,strings直接写入到输入sort而不是文件,并sort从输出读取strings而不是从文件读取。

    如果管道的左侧不能足够快地产生数据,则管道的右侧将被暂时阻塞;如果管道的右侧不能足够快地消耗数据,则管道的左侧将被暂时阻塞。这样,这两个实用程序就是同步的,并且保证您sort将阅读 的完整输出strings

  2. strings *.bin > bin.txt & sort -n bin.txt > logs1.txt

    这与上一个命令存在相同的问题,因为两者strings都是sort同时启动的。该程序在后台&启动,然后立即启动。两个实用程序彼此独立地写入或读取,并且有机会决定在到达文件末尾之前写入多少文件。stringssortbin.txtsort

  3. strings *.bin > bin.txt其次是sort -n bin.txt > logs2.txt

    在这里,您可以通过允许在对中间文件的内容进行排序之前strings完成中间文件的写入来手动同步这两个实用程序。没有问题,并且保证您能够从文件中读取完整的输出。bin.txtsortsortstrings

概括:您的前两个命令不同步stringssort实用程序。 by 的写入strings与 的读取无关sort。这意味着可以在完成写入所有数据sort之前找到中间文件的末尾。strings反过来,这意味着您可能会得到不完整的最终结果。您的不完整结果将包含的数据量取决于机会。

这两个实用程序同时启动的事实也意味着,sort甚至可能在 shell 有时间截断文件并启动之前将预先存在的文件读bin.txt到底strings

解决方案:首先将所有数据写入中间文件,然后从中读取,如第三个示例所示。或者,允许两个实用程序使用管道直接在它们之间通信数据,如我上面的建议所示:

strings -- *.bin | sort -n > logs1.txt

或者保留未排序输出的副本strings以供将来参考:

strings -- *.bin | tee bin.txt | sort -n > logs1.txt

有关 U&L 的更多相关阅读:

相关内容