194

What does <<< mean? Here is an example:

$ sed 's/a/b/g' <<< "aaa"
bbb

Is it something general that works with more Linux commands?

It looks like it's feeding the sed program with the string aaa, but isn't << or < usually used for that?

1
  • 6
    it seems < is for passing file (or directory), << @ for passing multiple lines (similar to the banner command in cisco switches; as terminated by a custom string @ in this case), and <<< to pass a string (instead of file). test them yourself with cat and you'll grasp it very quickly.
    – user86041
    Oct 5, 2017 at 10:32

4 Answers 4

262

Others have answered the basic question: what is it? Let's look at why it's useful.

You can also feed a string to a command's stdin like this:

echo "$string" | command

However in bash, introducing a pipe means the individual commands are run in subshells. Consider this:

echo "hello world" | read first second
echo $second $first

The output of the 2nd echo command prints just a single space. Whaaaa? What happened to my variables? Because the read command is in a pipeline, it is run in a subshell. It correctly reads 2 words from its stdin and assigns to the variables. But then the command completes, the subshell exits and the variables are lost.

Sometimes you can work around this with braces:

echo "hello world" | {
    read first second
    echo $second $first
}

That's OK if your need for the values is contained, but you still don't have those variables in the current shell of your script. To remedy this confusing situation, use a here-string

read first second <<< "hello world"
echo $second $first

Ah, much better!

10
  • 15
    In addition to here-strings, process substutitions are very useful for the same reasons. Jun 22, 2013 at 18:32
  • 9
    This is a fantastic explanation of <<< as well as pipes and sub-shells! I learned both from this.
    – David Mann
    May 12, 2017 at 1:29
  • 3
    One note, with the simple echo ...|read example, the pipeline can work to set the variables in the current shell if you (1) enable the "lastpipe" shell option (shopt -s lastpipe) and (2) disable job control (set +m) Aug 9, 2017 at 20:00
  • 3
    Very interesting. The case you give does not result in unexpected behavior using zsh.
    – Ryan Ward
    May 8, 2019 at 21:00
  • 4
    On my zsh, the output for echo $second $first is world hello
    – aafulei
    Jul 25, 2019 at 4:28
130

<<< denotes a here string.

$ cat <<< 'hi there'
hi there

It passes the word on the right to the standard input of the command on the left.


<< denotes a here document.

$ cat <<EOF
> hi
> there
> EOF
hi
there

EOF can be any word.

Here documents are commonly used in shell scripts to create whole files or to display long messages.

cat > some-file <<FILE
foo
bar
bar bar
foo foo
FILE

< passes the contents of a file to a command's standard input.

$ cat < /etc/fstab
/dev/sda2               /boot   ext4            nosuid,noexec,nodev,rw,noatime,nodiratime       0 2
/dev/sda4               /       ext4            rw,noatime,nodiratime,  0 1
/dev/sdb5               /var    ext4            nosuid,noexec,nodev,rw,relatime 0 2
 ...
7
  • 9
    Is there a reason why someone would want cat < /etc/fstab instead of just cat /etc/fstab? Or is cat just a suboptimal example here?
    – Griddo
    Jul 31, 2018 at 7:06
  • In the first case, cat opens the file, and in the second case, the shell opens the file, passing it as cat's standard input. quote from unix.stackexchange.com/questions/258931/…
    – star
    Apr 19, 2019 at 0:53
  • 7
    I can't think of a reason why cat < file would ever be better than cat file. However, there are some cases where there is a difference -- for example, grep string file is different from grep string < file in that the second form doesn't prefix "file:" in front of every line. "cat file | grep string" is better written as "grep string < file". Not that any of this is worth doing for performance alone these days, but it is better coding practice.
    – Brian C
    Jul 9, 2019 at 3:43
  • @star In cat < /etc/fstab, the shell opens the file, passing it as cat's standard input, whereas in cat /etc/fstab, cat opens the file. I think you'd interchanged them. Jun 5, 2021 at 13:11
  • @BrianC cat < file > foo would not create or overwrite foo if file could not be opened and so wouldn't potentially zap a file in an error scenario while cat file > foo would create/overwrite foo in that case.
    – Ed Morton
    Dec 26, 2021 at 14:09
19

Take a look at the Bash man page. This notation is part of what's called a here documents & here strings. It allows you the ability to generate multi-line data input as one continuous string. The variation you're asking about is called a here string.

excerpt from Bash man page

Here Strings
   A variant of here documents, the format is:

          <<<word

   The word is expanded and supplied to the command on its standard input.
7

It means here strings.

<<< strings

The strings is expanded and supplied to the command on its standard input.

In your example, strings aaa is feed to sed command via stdin.

Not the answer you're looking for? Browse other questions tagged or ask your own question.