管道命令未按预期工作我需要解释

管道命令未按预期工作我需要解释

我正在尝试执行以下操作

touch ~/scratches/scr6.txt | cat ~/scr.txt > ~/scratches/scr6.txt | cat /dev/null > ~/scr.txt

我不知道为什么 scr6.txt 总是空的,但是执行以下操作填充文件

cat ~/scr.txt > ~/scratches/scr6.txt

我想知道为什么第一个案例不起作用?

答案1

分解每个步骤:

  • touch ~/scratches/scr6.txt

    如果文件存在,则将时间戳更新为现在。如果不存在,则创建它。

  • cat ~/scr.txt > ~/scratches/scr6.txt

    读取 ~/scr.txt 并将内容写入 ~scratches/scr6.txt

  • cat /dev/null > ~/scr.txt

    清空 ~/scr.txt 文件

正如评论中提到的,在命令之间使用“&&”(AND)而不是“|” (PIPE) 会更合适。

答案2

好的,考虑到该scr.txt文件在执行命令之前包含一些文本并且scr6.txt尚不存在:命令

touch ~/scratches/scr6.txt | cat ~/scr.txt > ~/scratches/scr6.txt | cat /dev/null > ~/scr.txt
  1. 空的scr.txt文件 (cat /dev/null > ~/scr.txt
  2. 用(无)scr6.txt内容覆盖( )scr.txtcat ~/scr.txt > ~/scratches/scr6.txt
  3. 不执行任何操作,因为scr6.txt已经存在 ( touch ~/scratches/scr6.txt)

但是下面的命令

cat ~/scr.txt > ~/scratches/scr6.txt

只需scr.txt将内容写入scr6.txt

这就是为什么在第一种情况下两个文件都是空的,而在第二种情况下一切都按预期进行。

答案3

据我了解,管道进程或多或少都是同时启动的。通常,管道中的进程将从 stdin 读取或写入 stdout(或两者),并且 I/O 的完成将决定进程何时结束。

对于没有任何输出(例如touch)或任何标准输入(例如cat在文件上操作时)的进程,我通常希望程序会忽略它们的管道连接。

所以你基本上会得到三个并行运行的命令:

touch ~/scratches/scr6.txtcat ~/scr.txt > ~/scratches/scr6.txt, 和cat /dev/null > ~/scr.txt

如果 ~/scr.txt 尚不存在,命令 2 是否会失败并出现错误,这可能取决于操作系统,因为它将与命令 3 处于竞争条件。命令 1 和 2 也处于竞争条件,但race 只会影响文件的 ctime/mtime/atime。

答案4

简单来说:

touch命令是创建新的方式,空文件。它还用于更改现有文件和目录的时间戳(即最近访问和修改的日期和时间)。

在第一个命令中,它创建一个名为 的空文件scr6.txt

但在第二个命令中,它创建一个文件scr6.txt并将所有内容写入scr.txt该文件。

相关内容