Search code examples
bashshellstdoutheredoc

How does this redirection after a here-document work?


ftp -v -n <<! > /tmp/ftp$$ 2>&1
open $TARGET_HOST
user $TARGET_USER $TARGET_PWORD
binary
cd $TARGET_PUT_DIR
put $RESULTS_OUT_DIR/$FILE $FILE
bye
!

I inderstand that <<! is a "here-document" and is passing the commands to ftp until it reaches the delimiter "!" but I can't seem to wrap my head around this redirection:

> /tmp/ftp$$ 2>&1

Could someone please explain what is happening here?


Solution

  • First, the heredoc could be listed last without affecting what happens. Heredocs are traditionally written last but the <<NAME but can actually be written anywhere within the command. The order of << relative to the two > redirections doesn't matter since the former changes stdin and the latter change stdout and stderr.

    It'd be clearer if it were written:

    ftp -v -n > /tmp/ftp$$ 2>&1 <<!
        ...
    !
    

    Second, to explain the output redirections:

    • > /tmp/ftp$$ redirects stdout to a file named /tmp/ftp1234, where 1234 is the PID of the current shell process. It's an ad hoc way of making a temporary file with a relatively unique name. If the shell script were run several times in parallel each copy would write to a different temp file.

    • 2>&1 redirects stderr (fd 2) to stdout (fd 1). In other words, it sends error messages to the same file /tmp/ftp$$.