Search code examples
bashshellheredoc

How here document works in shell


While doing the input redirection, the shell opens the file on the right side of '<' with file descriptor 0, but in the case of the heredoc there is no such file to open, I am wondering what exactly shell does in this case.

cat > file.txt << EOF
line1
line2
EOF

Solution

  • In bash 5.0 and older, it creates a temporary file, writes the heredoc contents, and then redirects that file to stdin.

    We can see this happen with strace, which shows syscalls. Here are the relevant portions annotated with inline comments:

    $ 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