Bash/Python: does `echo` command insert a newline when acting as input to another command?

11,571

Solution 1

This command will answer your question:

echo 'hi' | od -c

The reason for the trailing \n character is that stdout on a terminal by default uses line buffering - meaning it will only display output data that ends with the newline character.

Play around with the printf command:

printf "%s"  foo
printf "%s\n" anotherfoo

Solution 2

If you look in the bash source, bash-4.2/builtins/echo.def you can see that the builtin echo command always (line 113) outputs a final \n (line 194) unless the -n was specified (line 198) or output of echo is used as a string (line 166). You can test this by doing

echo `echo "Ho ho ho"` | od -c

You will see only one \n because the output of echo "Ho ho ho" is evaluated as a string in the expression echo `echo "Ho ho ho"`.

It doesn't seem to have any relation to the terminal setup.

Share:
11,571
Bryce Thomas
Author by

Bryce Thomas

https://www.linkedin.com/in/brycethomas/

Updated on June 04, 2022

Comments

  • Bryce Thomas
    Bryce Thomas almost 2 years

    I have a simple python script line_printer.py:

    import fileinput
    i = 1
    for line in fileinput.input():
        print 'Line', str(i), ':', line.strip()
        i+=1
    

    I'm trying to understand how piping data in from the echo command to this script affects the result versus reading the data in from file.

    Consider the following call and output:

    $ echo -e "chicken\ncow\npig"
    chicken
    cow
    pig
    $
    

    This to me looks like echo has appended an invisble \n after the "g" in pig. So, how come when I call:

    echo -e "chicken\ncow\npig" | python line_printer.py
    

    I get:

    Line 1 : chicken
    Line 2 : dog
    Line 3 : cow
    

    as the output and not:

    Line 1 : chicken
    Line 2 : dog
    Line 3 : cow
    Line 4 : 
    

    At first I thought the behaviour of Python's fileinput module might be to discard the final line in a file if it is blank. But when I try using the contents of a file some_lines.txt:

    chicken
    dog
    cow
    <blank line>
    

    as the input:

    python line_printer.py some_lines.txt
    

    The output I get is:

    Line 1 : chicken
    Line 2 : dog
    Line 3 : cow
    Line 4 : 
    

    So why does line_printer.py give different results on the input depending on whether it originated from stdin versus originated from a file? Best I can tell, both stdin (from echo) and the file (from some_lines.txt) finish with a \n, so I would either expect the output of both to include the Line 4 : or the output of neither to include it.