cat > file < "END" 是如何工作的?

cat > file < "END" 是如何工作的?
$ cat > file << "END"
> asdf
> qwerty
> END
$ cat file
asdf
qwerty
$

不知道上面的技巧是如何工作的。

cat > file对我来说有点可以理解,这意味着 的输出cat被重定向并写入file.

<< "END"部分是如何工作的?我至少假设这意味着该字符串END应该被视为cat- 因此,如果有的话,我会假设最后file应该只包含一行三个字母:END。这怎么可能意味着“接受来自控制台的输入并将其重定向到cat直到用户键入该字符串,该字符串应被视为分隔符”超出了我的范围。

答案1

你的问题似乎不是如何此处文档工作,因为您已经正确描述了它们在脚本文件中的使用。看来你不明白它们的交互用途。以下是一个(非常简化的)速成课程,希望能够为您澄清问题。

Shell 与所有 Unix 进程一样,具有输入和输出流来来回读取和写入数据。它们至少有一个输入流(称为stdin)和两个输出流(stdoutstderr),但它们可以根据需要打开和关闭任意多个输入流,以进行读取和写入(主要是从文件中读取或写入文件)。进程如何处理它们的流取决于它们。cat,例如,当不带参数调用时,将其复制stdinstdout. Shell 通常将其输入流解释为要执行的命令(并根据某种语法为这些命令设置输入和输出流)。

输入数据从哪里来?它们可以来自发送它们的其他进程,可以从文件中读取,也可以由用户直接键入,这是 shell 的stdin.在这种情况下,必须有另一个程序获取用户输入并将其加载到流中。这样的程序称为 a tty,在这种情况下我们说流是附于一个tty(这tty与为其提供窗口的终端仿真程序不同,但从广义上讲,您也可以说流是连接到终端。

Shell 知道它们何时stdin附加到 atty并且表现不同,例如在等待输入时打印提示,但实际上没有太多其他差异。提示通常类似于user@host:current_path$。其确切内容可以通过更改变量来定义PS1。通常的约定是$,当您是普通用户时,它结束,#当您是 时,它结束root

当您执行脚本时,shell 将输入流附加到包含该脚本的文件,并从中读取命令。如果其中一个命令包含此处文档,也就是说,类似于<<END,这意味着:从现在开始,直到仅包含此终止符的行,停止将流数据解释为命令并将它们传递给stdin您要执行的命令(cat在您的情况下) ,可能会有一些现在不会打扰我们的损坏。这是你已经知道的,尽管可能是从另一个角度来看的。

当输入附加到 a 时tty,此处文档的含义相同:停止将流数据解释为命令并将它们传递到stdin您要执行的命令的 ,直到终止符。唯一的区别是,等待输入时打印提示;该提示与 shell 将输入数据解释为命令时打印的提示不同,只是让您知道它们将被传递。它由变量定义PS2,其值默认为>。键入 后,您会在每一行的开头看到它cat file > file << "END",直到读取终止符,此时 shell 恢复其正常行为,打印其PS1-prompt 并等待输入被解释为命令。

相关内容