What does the Bash operator <<< (i.e. triple less than sign) mean?

19,559

Solution 1

It redirects the string to stdin of the command.

Variables assigned directly before the command in this way only take effect for the command process; the shell remains untouched.

Solution 2

From man bash

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

     <<<word

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

The . on the IFS line is equivalent to source in bash.

Update: More from man bash (Thanks gsklee, sehe)

IFS The Internal Field Separator that is used for word splitting after expansion and to split lines into words with the read builtin command. The default value is "<space><tab><new‐line>".

yet more from man bash

The environment for any simple command or function may be augmented temporarily by prefixing it with parameter assignments, as described above in PARAMETERS. These assignment statements affect only the environment seen by that command.

Solution 3

The reason that IFS is not being set is that bash isn't seeing that as a separate command... you need to put a line feed or a semicolon after the command in order to terminate it:

$ cat /tmp/ifs.sh
LINE="7.6.5.4"
IFS='.'  read -a ARRAY <<< "$LINE"
echo "$IFS"
echo "${ARRAY[@]}"
$ bash /tmp/ifs.sh 
7 6 5 4

but

$ cat /tmp/ifs.sh 
LINE="7.6.5.4"
IFS='.';  read -a ARRAY <<< "$LINE"
echo "$IFS"
echo "${ARRAY[@]}"
$ bash /tmp/ifs.sh 
.
7 6 5 4

I'm not sure why doing it the first way wasn't a syntax error though.

Share:
19,559

Related videos on Youtube

gsklee
Author by

gsklee

Updated on June 04, 2022

Comments

  • gsklee
    gsklee 6 months

    What does the triple-less-than-sign bash operator, <<<, mean, as inside the following code block?

    LINE="7.6.5.4"
    IFS=. read -a ARRAY <<< "$LINE"
    echo "$IFS"
    echo "${ARRAY[@]}"
    

    Also, why does $IFS remain to be a space, not a period?

    • mosh
      mosh almost 5 years
      Another use of this operator (instead of named pipes with mknod) when you need multiple pipes in a single | pipline: eg. echo data | command --data-on-stdin --other-data-on-fd-3 3<<<'other-data'
  • gsklee
    gsklee about 11 years
    The . seems like a way to define a custom delimiter for $LINE
  • gsklee
    gsklee about 11 years
    How do I modify it to use a custom multichar delimiter? Say, ==>? How should I quote the string?
  • Ignacio Vazquez-Abrams
    Ignacio Vazquez-Abrams about 11 years
    You can't. $IFS is always interpreted as a series of single characters.
  • Tanktalus
    Tanktalus about 11 years
    Because the first way is how you temporarily set env vars for a single command. They automatically reset back to their previous values when that command is complete. I use this all the time to set debug flags or what have you but only temporarily.
  • Guna over 4 years
    But when I want to split the array using newline. Only the first item is getting added to the hostArray. But the host has 4 items. host=$(mysql -S $socket $catalog --skip-column-names -e "select host from mysql.user); echo "Host: $host"; IFS=$'\n';read -ra hostArray <<< "$host"; echo "HostArray:$hostArray" #This prints only 1 item. But there are 4 items; What is wrong here?
  • Davos
    Davos over 1 year
    @Guna I'm a few years too late but anyway others might wonder so...in this part <<< "$host" , when you reference an array like "$host" it implies the default index of zero so it's really doing "$host[0]". What you need there is "${host[@]}"