此处文档在 shell 中的工作原理

How here document works in shell

在进行输入重定向时,shell 打开文件描述符为 0 的 '<' 右侧的文件,但是在 heredoc 的情况下没有这样的文件可以打开,我是想知道 shell 在这种情况下到底做了什么。

cat > file.txt << EOF
line1
line2
EOF

直到 bash 5.1,它将 here-document 的内容复制到一个临时文件,然后将输入重定向到该文件。

从 5.1 开始,这取决于 here-document 的大小。如果它适合管道缓冲区,它会创建一个管道并将 here-document 的内容写入管道。如果它太大了,它会恢复到临时文件方法。

在 bash 5.0 及更早版本中,它会创建一个临时文件,写入 heredoc 内容,然后将该文件重定向到标准输入。

我们可以在显示系统调用的 strace 中看到这种情况。以下是用内联注释注释的相关部分:

$ strace -f bash -c $'cat > file.txt << EOF\nline1\nline2\nEOF'

# Open a temporary file `/tmp/sh-thd-1641928925`.
[pid  8292] open("/tmp/sh-thd-1641928925", O_WRONLY|O_CREAT|O_EXCL|O_TRUNC, 0600) = 3

# Write the heredoc contents to the file.
[pid  8292] dup(3)                      = 4
[pid  8292] write(4, "line1\nline2\n", 12) = 12
[pid  8292] close(4)                    = 0

# Open the file read-only.
[pid  8292] open("/tmp/sh-thd-1641928925", O_RDONLY) = 4

# Close the original file and unlink it so there's no filesystem
# reference. The file will be fully deleted once all fds are closed.
[pid  8292] close(3)                    = 0
[pid  8292] unlink("/tmp/sh-thd-1641928925") = 0

# Redirect the file to stdin.
[pid  8292] dup2(4, 0)                  = 0
[pid  8292] close(4)                    = 0

# Execute `cat`.
[pid  8292] execve("/usr/bin/cat", ["cat"], 0x187c160 /* 113 vars */) = 0