我是 Linux 和 shell 脚本新手,我正在努力学习基础知识。我目前正在阅读重定向章节,其中正在解释此处的文档。我无法真正理解下面的代码如何与cat
命令结合使用。如果有人可以告诉我吗?
cat << EOF
line1
line2
line3
EOF
我非常了解如何<< EOF
运作。关键字表示输入结束。我的问题是;cat
将文件名作为输入流;以便它可以在输出流上打印其内容。以上是如何工作的内部?我们没有在任何地方指定文件名。 shell 是否在内部创建一些临时文件并将其提供给cat
?我希望我的问题很清楚。
答案1
当cat
在命令行上未给出文件名时(或者文件名只是-
),则它会切换到从标准输入读取。
这意味着与
cat <<END
something something
END
cat
将注意到它没有被赋予文件名,并将继续从到达其标准输入流的此处文档中读取。
您可以cat
从其标准输入和文件中读取
cat - filename <<END
something something
END
这将导致此处文档的内容与 的内容连接起来filename
。如果参数的顺序是,filename -
那么这也将是数据连接的顺序。
请注意,这-
对 shell 来说并不特殊,并且被cat
实用程序(以及其他一些实用程序)专门解释为“标准输入”。如果您有一个-
需要运行的实际文件cat
,请使用cat ./-
,即使用路径指定文件名。
出于所有目的,您可以考虑将此处文档直接输入到实用程序中,作为创建临时文件的简写,然后使用附加到标准输入流的文件来调用该实用程序:
printf 'some contents' >tmpfile
utility <tmpfile
rm -f tmpfile
Here-documents 实际上可能不会以这种方式实现(它可能是 FIFO(命名管道)),但这并不是完全错误的思考方式。
阅读bash
源代码,似乎特定的 shell 通过使用mkstemp()
库函数创建一个临时文件(如果可用)来实现此处文档,否则它会尝试创建一个随机文件名来写入。然后将文档的内容写入该文件,并在读取该文件的任何内容的标准输入上提供数据,就像它来自文件一样,使用<
.请参阅源代码分发中的redir.c
和。lib/sh/tmpfile.c
bash