44

The following examples show that a newline is added to a here-string.
Why is this done?

xxd -p <<<'a'  
# output: 610a

xxd -p <<<'a
'
# output: 610a0a
46

The easy answer is because ksh is written that way (and bash is compatible). But there's a reason for that design choice.

Most commands expect text input. In the unix world, a text file consists of a sequence of lines, each ending in a newline. So in most cases a final newline is required. An especially common case is to grab the output of a command with a command susbtitution, process it in some way, then pass it to another command. The command substitution strips final newlines; <<< puts one back.

tmp=$(foo)
tmp=${tmp//hello/world}
tmp=${tmp#prefix}
bar <<<$tmp

Bash and ksh can't manipulate binary data anyway (it can't cope with null characters), so it's not surprising that their facilities are geared towards text data.

The <<< here-string syntax is mostly only for convenience anyway, like << here-documents. If you need to not add a final newline, use echo -n (in bash) or printf and a pipeline.

7
  • Much more thorough than my answer.
    – Mike
    Sep 6 '11 at 0:02
  • 2
    Bash may have borrowed here-strings from ksh93, but ksh in turn borrowed them from zsh, which got them from the Plan 9 shell rc.
    – Mark Reed
    Jan 7 '14 at 22:04
  • 2
    <<< was introduced to the Bourne world by zsh, not ksh. And it was inspired by a similar operator in the Unix port of rc which did not add that extra newline character. Interestingly, the =(<<<text) operator doesn't add that newline in zsh. Nov 6 '15 at 17:21
  • If you wonder about the interest in this answer is because of this question in SO.
    – fedorqui
    Jun 9 '16 at 14:41
  • 1
    Is there any way to write the here-string (without using any other utility like printf, etc) avoiding the tailing newline in bash? Like @StéphaneChazelas pointed is possible in zsh.
    – CTodea
    Jun 20 '18 at 15:47
5

One scenario in which it is practical to have newlines appended to here-strings is when using the read command when set -e mode is active. Recall that set -e causes a script to terminate when it (more or less) encounters statements that generate a non-zero status code. Consider that read generates a non-zero status code when it encounters a string without newlines:

#!/bin/bash
set -e

# The following statement succeeds because here-strings append a newline:
IFS='' read -r <<< 'newline appended'
echo 'Made it here'

# The following statement fails because 'read' returns a non-zero status
# code when no newlines are encountered.
printf 'no newline' | IFS='' read -r
echo 'Did not make it here'
-3

I think that's the only way to get a newline at the end of a here-string, proof:

xxd <<<`echo -ne "a\n"`

It would appear that the here-string operator strips newlines unless they are given in the syntax you submitted.

1
  • 4
    It's the command substitution that's stripping the final newline. You could simplify this to xxd <<<$(echo a). Sep 6 '11 at 0:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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