Reputation: 10799
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.
Upvotes: 2
Views: 11810
Reputation: 4841
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.
Upvotes: 1
Reputation: 16389
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
Upvotes: 1