在特定目录中,我创建了一个名为“fileName”的文件并向其中添加内容。当我输入
cat fileName
时,它的内容会打印在终端上。现在我使用以下命令:
cat fileName>fileName
没有显示错误。现在,当我尝试使用查看文件内容时,
cat fileName
终端中没有显示任何内容,文件为空(当我检查时)。这是什么原因呢?
>
即重定向到同一文件将在调用 cat 命令之前创建/截断该文件,因为它具有更高的优先级。您可以通过使用中间文件然后从中间文件到实际文件来避免相同的情况,或者您可以使用 tee 像:
cat fileName | tee fileName
为了澄清 SMA 的答案,文件被截断,因为重定向是由 shell 处理的,shell 在调用命令之前打开文件进行写入。当您运行
cat file > file
时,shell 会截断并打开文件进行写入,将 stdout 设置为文件,然后执行 ["cat", "file"]
。因此,您将不得不使用其他命令来完成任务,例如 tee
这里给出的答案是错误的。无论使用重定向还是管道,您都会遇到截断问题,尽管有时它可能“看起来”可以工作,具体取决于文件大小或管道长度。这是一个竞争条件,因为读取器可能有机会在写入器开始之前读取部分或全部文件,但管道的重点是同时运行所有这些文件,因此它们将同时启动tee 可执行文件要做的第一件事是打开输出文件(并在此过程中截断它)。在这种情况下,唯一不会出现问题的方法是管道末端将整个输出加载到内存中,并且仅在关闭时将其写入文件。这种情况不太可能发生,并且失去了拥有管道的意义。 使其可靠的正确解决方案是仅写入临时文件,然后将临时文件重命名回原始文件名:
TMP="$(mktemp fileName.XXXXXXXX)"
cat fileName | grep something | tee "${TMP}"
mv "${TMP}" fileName
>
时,目标文件变空,然后接受重定向。
所以,
cat fileName>fileName
cat
filename文件并且不输出任何内容 没有任何内容重定向到
文件。 要避免这种行为,最简单的方法是
SMA的答案。
但有些人不喜欢使用 tee
命令,因为有额外的屏幕输出。
简单易懂。
但有些人避免使用临时文件。
正确使用重定向可能是一种很好的方式,但很难理解。
pistache 对其他问题的回答
介绍了如何做到这一点。
有多种方法可以使用重定向,我会这样做。
{ rm file; cat > file; } < file
抱歉我的英语不好。我不是本地人。