How to understand "cat > file_name << blah" command?

In following command cat takes the content of here-doc and redirects it to file named conf:

cat > conf << EOF
var1="cat"
var2="dog"
var3="hamster"
EOF

How to understand the order of commands here? Does bash first processes everything else(here-doc part) and as a final step it looks the > conf part?

Asked By: Martin

||

Well, let’s find out:

unset file
cat >"$file" <<EOF
this is not in ${file=./myfile}
EOF

bash: : No such file or directory

Dang. I guess it must be doing the >"$file" part first then. But what if…?

unset file
<<EOF cat >"$file"
this is in ${file=./myfile}
EOF

…no error…?

cat ./myfile

this is in ./myfile

As it appears, order matters.

Answered By: mikeserv

When bash creates the process to run cat, it opens conf for write on file descriptor 1 and opens a temporary file (for the here-document) for read on file descriptor 0, before execing the program. In this case, it doesn’t really matter in which order those actions happen.

Order does become significant when file descriptors are reassigned, e.g. with 2>&1.

Answered By: Toby Speight

Here-Document is a kind of shell redirection, so the shell will perform it as normal redirection, from beginning to the end (or from left to right, or order of appearance). This’s defined by POSIX:

If more than one redirection operator is specified with a command, the
order of evaluation is from beginning to end.


In your command, cat will perform > conf first, open and truncate conf file for writing, then reading data from Here-Document.

Using strace, you can verify it:

$ strace -f -e trace=open,dup2 sh -c 'cat > conf << EOF
var1="cat"
var2="dog"
var3="hamster"
EOF
'
...
open("conf", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
dup2(3, 1)                              = 1
dup2(3, 0)                              = 0
...
Answered By: cuonglm
Categories: Answers Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.