Bash/Python: команда `echo` вставляет новую строку, действуя как вход в другую команду?
У меня есть простой python script line_printer.py
:
import fileinput
i = 1
for line in fileinput.input():
print 'Line', str(i), ':', line.strip()
i+=1
Я пытаюсь понять, как данные о трафике из команды echo
на этот script влияют на результат по сравнению с чтением данных из файла.
Рассмотрим следующий вызов и вывод:
$ echo -e "chicken\ncow\npig"
chicken
cow
pig
$
Это для меня выглядит как echo
добавило invisble \n
после "g" в свиньи. Итак, как получилось, когда я звоню:
echo -e "chicken\ncow\npig" | python line_printer.py
Я получаю:
Line 1 : chicken
Line 2 : dog
Line 3 : cow
как вывод, а не:
Line 1 : chicken
Line 2 : dog
Line 3 : cow
Line 4 :
Сначала я думал, что поведение модуля Python fileinput
может состоять в том, чтобы отбросить окончательную строку в файле, если она пуста. Но когда я пытаюсь использовать содержимое файла some_lines.txt
:
chicken
dog
cow
<blank line>
в качестве входа:
python line_printer.py some_lines.txt
Выход, который я получаю:
Line 1 : chicken
Line 2 : dog
Line 3 : cow
Line 4 :
Итак, почему line_printer.py
дает разные результаты на входе в зависимости от того, возникла ли она из stdin или из файла? Лучшее, что я могу сказать, как stdin (от echo
), так и файл (от some_lines.txt
) заканчиваются на \n
, поэтому я либо ожидал, что вывод обоих включит Line 4 :
, либо вывод не будет включите его.
Ответы
Ответ 1
Эта команда ответит на ваш вопрос:
echo 'hi' | od -c
Причиной для возвращаемого символа \n
является то, что stdout на терминале по умолчанию использует буферизацию строк - это означает, что он будет отображать только выходные данные, которые заканчиваются символом новой строки.
Играйте с командой printf:
printf "%s" foo
printf "%s\n" anotherfoo
Ответ 2
Если вы посмотрите в источнике bash, bash -4.2/builtins/echo.def, вы увидите, что команда builtin echo
всегда (строка 113) выводит окончательный \n
(строка 194), если только был указан -n
(строка 198), или вывод echo
используется как строка (строка 166). Вы можете проверить это, выполнив
echo `echo "Ho ho ho"` | od -c
Вы увидите только один \n
, потому что вывод echo "Ho ho ho"
оценивается как строка в выражении echo `echo "Ho ho ho"`
.
Он не имеет никакого отношения к настройке терминала.