How does cat > file << "END" work?

16,066

Your problem seems not to be how here-documents work, as you have correctly described their use in script files. It seems that you don’t understand their interactive use. The following is a (much simplified) crash course which will hopefully clarify the matter for you.

Shells, like all Unix processes in general, have input and output streams to read and write data, to and fro. They have at least one input stream (called stdin) and two output streams (stdout and stderr), but they can open and close as many as they want, for reading and for writing (mostly, to read from files or write to them). What processes do with their streams depends on them. cat, for instance, when called without arguments, copies its stdin to stdout. Shells usually interpret their input streams as commands to be executed (and set up input and output streams for those commands according to some syntax).

Where do input data come from? They can come from other processes sending them, they can be read from files, or they can be typed directly by the user, which is the most normal situation for a shell’s stdin. In this case, there must be another program taking the user input and loading it into the stream. Such a program is called a tty and in this case we say that the stream is attached to a tty (the tty is different from the terminal emulation program which provides a window for it, but you can also, broadly speaking, say that the stream is attached to a terminal.)

Shells know when their stdin is attached to a tty and behave differently, for instance printing a prompt when waiting for input, but there are really not many other differences. A prompt is usually something like user@host:current_path$. Its exact contents can be defined by altering the variable PS1. A usual convention is that it ends with $ when you are a normal user, and with # when you are root.

When you execute a script, the shell attaches an input stream to the file containing it, and reads commands from it. If one of the commands contains a here-document, that is, something like <<END, this means: from now on, up to a line containing exactly only this terminator, stop interpreting the stream data as commands and pass them on to the stdin of the command you are going to execute (cat in your case), possibly with some mangling that will not bother us now. This is what you already know, albeit possibly in another perspective.

When input is attached to a tty, a here-document means the same: stop interpreting the stream data as commands and pass them on to the stdin of the command you are going to execute, up to the terminator. The only difference is, print a prompt when waiting for input; this prompt is different from the one the shell would print if it were going to interpret the input data as commands, just to let you know that they will be passed on. It is defined by the variable PS2 and its value defaults to >. You see it at the beginning of every line after typing cat file > file << "END", until the terminator is read, when the shell resumes its normal behavior, prints its PS1-prompt and waits for input to be interpreted as commands.

Share:
16,066

Related videos on Youtube

gaazkam
Author by

gaazkam

Apparently, this user prefers to keep an air of mystery about him.

Updated on September 18, 2022

Comments

  • gaazkam
    gaazkam over 1 year
    $ cat > file << "END"
    > asdf
    > qwerty
    > END
    $ cat file
    asdf
    qwerty
    $
    

    Not sure how does the above trick work.

    cat > file is somewhat understandable for me, it means that the output of cat is being redirected and written to file.

    How does this << "END" part work? I’d at least assume that it means that the string END should be treated as input to cat – thus, if anything, I’d assume that in the end file should contain only one line with three letters: END. How possible that this means “accept input from console and redirect it to cat until the user types this string, which should be treated as a delimiter“ is beyond me.

    • don_crissti
      don_crissti over 7 years
    • icarus
      icarus over 7 years
      Do you want to know what it does or how it is implemented?
    • Weijun Zhou
      Weijun Zhou about 5 years
      "I’d at least assume that it means that the string END should be treated as input to cat – thus, if anything, I’d assume that in the end file should contain only one line with three letters: END". Try cat > file <<< END in bash.
  • grochmal
    grochmal over 7 years
    It is a good answer alright (+1). Although, since it is newbie-oriented, i'd add one or two sentences more about the prompt. The beginning of the third paragraph may be confusing to a newbie because he will not know that the > character is actually a PS2 prompt.