有趣的 bash 行为
The Interesting bash behaviour
为什么这个命令(创建一个空文件夹,更改到它,触摸一个文件,调用 ls
然后 cat
ing 它)显示两个文件?
root@ubuntu:~# mkdir a ; cd a ; touch b ; ls > c ; cat c
b
c
我相信我应该只得到 "b"。
文件已创建(或截断),因此 ls
的输出可以重定向到它。
因此,ls
看到了文件。
当您将 ls
的输出重定向到文件 c
时,这是一个先有鸡还是先有蛋的问题:
如果 c
不会预先创建,这意味着 shell 需要将输出存储在缓冲区中并(最后)将该缓冲区写入文件。
因为在很多情况下这不是最好的方法(因为内存管理、对在完成前被中断的命令的失败管理等),文件是预先创建的。
因此,命令的标准输出可以替换为新创建的文件,命令输出可以流到该文件。
命令的标准输出重定向
ls > c
在执行命令 ls
之前为 c
创建文件句柄。 touch b
(以及 b
的可见性是一个转移注意力的问题)。例如,
mkdir t ; cd t ; ls > a ; cat a
将显示 a
( 因为 >
在 ls
之前创建 a
是 exec
d ).
了解 ls
的输出被重定向到文件 c,我们需要查看 shell 用于执行此类命令的过程。
当shell处理命令行时(非常简化):
- 将行分成标记(通常在空格处)。
- 解释所有标记(命令、参数、重定向)。
- 设置输入和输出的结构,包括任何重定向。
- 执行命令,将其输出发送到正确的位置。
由于需要在第 3 步设置输出,任何将接收输出的文件都必须存在,如果不存在则创建。
然后,在执行命令(在本例中为 ls)时,文件(在本例中为 c)必须已经存在才能接收命令输出。
因此看到文件c的内容中列出的两个文件是正确的
为什么这个命令(创建一个空文件夹,更改到它,触摸一个文件,调用 ls
然后 cat
ing 它)显示两个文件?
root@ubuntu:~# mkdir a ; cd a ; touch b ; ls > c ; cat c
b
c
我相信我应该只得到 "b"。
文件已创建(或截断),因此 ls
的输出可以重定向到它。
因此,ls
看到了文件。
当您将 ls
的输出重定向到文件 c
时,这是一个先有鸡还是先有蛋的问题:
如果 c
不会预先创建,这意味着 shell 需要将输出存储在缓冲区中并(最后)将该缓冲区写入文件。
因为在很多情况下这不是最好的方法(因为内存管理、对在完成前被中断的命令的失败管理等),文件是预先创建的。
因此,命令的标准输出可以替换为新创建的文件,命令输出可以流到该文件。
命令的标准输出重定向
ls > c
在执行命令 ls
之前为 c
创建文件句柄。 touch b
(以及 b
的可见性是一个转移注意力的问题)。例如,
mkdir t ; cd t ; ls > a ; cat a
将显示 a
( 因为 >
在 ls
之前创建 a
是 exec
d ).
了解 ls
的输出被重定向到文件 c,我们需要查看 shell 用于执行此类命令的过程。
当shell处理命令行时(非常简化):
- 将行分成标记(通常在空格处)。
- 解释所有标记(命令、参数、重定向)。
- 设置输入和输出的结构,包括任何重定向。
- 执行命令,将其输出发送到正确的位置。
由于需要在第 3 步设置输出,任何将接收输出的文件都必须存在,如果不存在则创建。
然后,在执行命令(在本例中为 ls)时,文件(在本例中为 c)必须已经存在才能接收命令输出。
因此看到文件c的内容中列出的两个文件是正确的