这里的文档如何在shell中工作



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

cat > file.txt << EOF
line1
line2
EOF

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

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

$ strace -f bash -c $'cat > file.txt << EOFnline1nline2nEOF'
# 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, "line1nline2n", 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

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

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

最新更新