224

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?

Daniel Jonsson
  • 2,395
  • 3
  • 14
  • 9
  • 8
    it seems `<` is for passing file (or directory), `<< @` for passing multiple lines (similar to the `banner` command in [tag: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. –  Oct 05 '17 at 10:32

4 Answers4

288

Others have answered the basic question: What is it? (Answer: It's a here string.)

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!

Matthias Braun
  • 7,797
  • 7
  • 45
  • 54
glenn jackman
  • 84,176
  • 15
  • 116
  • 168
  • 15
    In addition to here-strings, [process substutitions](http://www.gnu.org/software/bash/manual/bashref.html#Process-Substitution) are very useful for the same reasons. – glenn jackman Jun 22 '13 at 18:32
  • 11
    This is a fantastic explanation of <<< as well as pipes and sub-shells! I learned both from this. – David Mann May 12 '17 at 01: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`) – glenn jackman Aug 09 '17 at 20:00
  • @glennjackman, What's the different between here-strings vs replacing it with an echoed temporary file? – Pacerier Mar 06 '18 at 10:59
  • Functionally nothing. With a here string, you don't have to delete a temp file. – glenn jackman Mar 06 '18 at 11:03
  • Doesn't seem to work on Windows' Ubuntu Bash: `dradcliffe:~$ read first second <<< big joe // nothing` – Dean Radcliffe May 23 '18 at 21:07
  • 1
    First the here string is a single string so if it contains whitespace you need quotes. Second the read command doesn't output anything so you'll have to clarify "nothing" – glenn jackman May 23 '18 at 21:43
  • 3
    Very interesting. The case you give does not result in unexpected behavior using zsh. – Ryan Ward May 08 '19 at 21:00
  • 4
    On my zsh, the output for `echo $second $first` is `world hello` – aafulei Jul 25 '19 at 04:28
  • For zsh the last command of a pipeline is run in the parent shell ([blog post](https://www.vidarholen.net/contents/blog/?p=178)), though unfortunately I couldn't(?) infer this directly from the [docs](http://zsh.sourceforge.net/Doc/Release/Shell-Grammar.html#Simple-Commands-_0026-Pipelines). Anyway, when to use a subshell is apparently [not specified by posix](https://unix.stackexchange.com/questions/80362/what-does-mean). – Ben Jul 24 '20 at 13:04
  • Am I right to think, this is a "bashism"? It's not backed by POSIX, is it? – d.c. Nov 21 '22 at 20:09
  • bash usually steals features from Korn shell or zsh. I don't know who invented it. – glenn jackman Nov 22 '22 at 00:47
146

<<< 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
 ...
RomanPerekhrest
  • 29,703
  • 3
  • 43
  • 67
  • 10
    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? – Gerrit-K Jul 31 '18 at 07: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 https://unix.stackexchange.com/questions/258931/difference-between-cat-and-cat – star Apr 19 '19 at 00: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 09 '19 at 03: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. – Ray Jasson Jun 05 '21 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 '21 at 14:09
  • Hi @ed-morton - In testing, `cat < foo > file` doesn't actually overwrite foo; and If there is an rare error reading the input file, `cat foo` is able to report the file name, whereas it cannot when presented with a stream via `< file`. Of course, BOTH forms are absolutely terrible shell programming practice and should never be done. Instead, use the `cp` command, or output to an intermediate file and use `if [ -s foo.tmp ]` to test for output file validity before then moving the output over the top of any existing file called foo. – Brian C Dec 27 '21 at 09:37
  • @BrianC I didn't suggest that `cat < foo > file` would overwrite `foo`, of course it doesn't. You misread my comment, it has nothing to do with overwriting the input file. I was providing a case where `cat < file` would be better than `cat file` in response to your comment ["I can't think of a reason why cat < file would ever be better than cat file"](https://unix.stackexchange.com/questions/80362/what-does-mean/80368?noredirect=1#comment978966_80368) – Ed Morton Dec 27 '21 at 12:18
21

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.

NOTE: For more info you can also check out the Bash Reference Manual which discusses Here Strings.

slm
  • 363,520
  • 117
  • 767
  • 871
9

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.

cuonglm
  • 150,973
  • 38
  • 327
  • 406