shell 中 `>` `>` 的行为是什么

shell 中 `>` `>` 的行为是什么

我知道这三个函数的原理。以及为什么cat < file > file会清除文件内容。但我不明白为什么它cat < file >> file不是将内容写入两次,而是像在无限 while 循环中一样将内容连接起来。

答案1

好吧,我的cat(在 Kubuntu 中)说完input file is output file就退出了。我知道你cat不那么聪明(或者不那么懒惰)。

您所观察到的现象很容易解释。cat读取和写入都是分块进行的。假设第一个块未到达文件末尾 (EOF),并且其内容在同一文件的末尾连接起来。读取cat前进了一定数量的字节,但文件末尾“偏离”了相同的数量。实际上,cat它再次与开始时一样远离 EOF。并且它一直持续下去。

就好像你每跑100米,终点线就会离你多100米。你永远也到不了终点,而跑过的距离会无止境地增长。

除非原来的距离为 100 米或更短。在这种情况下,你会在终点线重新定位之前到达终点线。类似地cat 可能如果文件足够小,则完成,但我对此表示怀疑。我期望cat只有当它尝试再次读取并且能够读取 0 个字节时,它才“知道”它已经到达了 EOF,不能再读取了。这意味着它在上一步中已经读取到 EOF,此时它读取了超过 0 个字节。但在你的情况下,如果它在上一步中读取了超过 0 个字节,那么文件会立即增大,并且仍然有数据要读取。

我预测有两种情况会让你cat停止:

  • 当文件为空(0字节长度)时,
  • 当文件不存在并且您更改重定向的顺序时(即将cat >> file < file会工作,cat < file >> file将会抛出错误;这是因为重定向是从左到右“提供”的,>>如果需要则会创建文件,<要求文件存在)。

一般来说,在单个命令中使用带有 stdin 和 stdout(或/和 stderr)重定向的同一文件会带来麻烦。不过,如果你需要这样做,sponge公用事业(例如在moreutilsUbuntu、Debian 的软件包中)。

sponge读取标准输入并将其写入指定文件。与 shell 重定向不同,sponge 会在打开输出文件之前吸收所有输入。这允许限制从同一文件读取和写入的管道。

如果没有指定输出文件,sponge则输出到标准输出。

而不是cat < file >> file运行sponge < file >> file。它将执行您期望的操作cat(我认为,除非文件足够大,以至于在被吸收时耗尽您的资源)。

另一种方法是< file cat | cat >> file。由于两个cat-s 之间的缓冲,第一个 -s 会在第二个 -s 扩展文件之前真正到达 EOF 并退出,如果文件足够小。从一个小文件(但不为空)开始重复此命令几次,文件最终会变得足够大,使命令的行为就像使用一个的原始命令一样cat。注意< file cat | unbuffer cat >> file即使对于非常小的文件也会摆脱缓冲区和循环。

答案2

嗯,基本上它的工作原理如下:

>用于覆盖文件的内容。例如:echo "HELLO WORLD" > file.txt

>>用于将内容附加到文件。例如:echo "New line" >> file.txt

<您可以使用文件作为输入并重定向到另一个文件。例如:cat < file.txt > file2.txt。一个实际的例子是ftp myftpbox.com < commands.txt,这将连接到 FTP 并执行文件中的命令列表commands.txt

笔记:使用时要小心,>因为您可以在没有任何确认的情况下覆盖现有文件,您可以通过运行来改变它set -o noclobber

我希望这有帮助。

相关内容