LINUX.ORG.RU

Разница между echo и printf в Linux

 


0

1

Приветствую.

Есть скрипт, разумеется на похапе, хотя это и не столь важно.

Суть скрипта - проверять на существование файла, и если файл найден, то читать его построчно (хотя не обязательно) и отправлять строки в UART. Строки не простые, а специально сформированные. Пример: POP02\xe2\x0b.

Запустили мы программу в одной консоли, она висит и проверяет наличие файла.

В другой консоли мы записываем желаемую команду.

Так вот, если эту команду писать в файл как echo "POP02\xe2\x0b" > /file, то инвертор возвращает ошибку. Если писать как printf "POP02\xe2\x0b" > /file - нет.

Важно: проверка и удаление \n в скрипте выполняются, выводится проверочная строка, лишних символов не видно. Но они есть.

Вопрос: что добавляет echo того, чего не добавляет printf?

★★★★★

Последнее исправление: windows10 (всего исправлений: 1)
Ответ на: комментарий от egzakharovich

Сразу видно, что документацию не читаем, тред на ЛОРе начинаем…

Нет, это вы вопрос не прочитали. Вопрос сформулирован предельно точно и понятно, и не подразумевает никаких решений несуществующих проблем, а только вопрос что записывает echo.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от windows10

Тогда тут речь скорее о том, чего echo по умолчанию делает и не делает.

А именно, не обрабатывает backslash escapes и добавляет trailing newline.

Когда printf обрабатывает backslash escapes всегда и не добавляет trailing newline сам.

Потом нужно задать себе вопрос, а надо ли, чтобы команда обрабатывала backslash escapes или выводила всё как есть?

Вы попробуйте echo -en "POP02\xe2\x0b" в терминале…

egzakharovich
()
Последнее исправление: egzakharovich (всего исправлений: 1)

Буквально можно прям в терминале запустить echo "POP02\xe2\x0b" и printf "POP02\xe2\x0b", и увидеть разницу.

neumond ★★
()
Ответ на: комментарий от egzakharovich

Вы попробуйте echo -en «POP02\xe2\x0b» в терминале…

Да, так работает.

Понял, благодарю.

windows10 ★★★★★
() автор топика
Ответ на: комментарий от windows10

Чтобы прям совсем усложнить жизнь, такой пример ещё:

$ echo "\"'\""
"'"
$ echo $'Line\nbreak'
Line
break

Здесь сам баш применил escape последовательности до того как они стали параметром echo. Сам по себе echo ничего изначально и не делает, только выводит в stdin свои параметры через пробел, ровно как они пришли в argv:

$ echo "$(printf "POP02\xe2\x0b")"
POP02�
neumond ★★
()
Ответ на: комментарий от IPR

Маны пишут только для неудачников, да?

теперь и для ИИ )

x905 ★★★★★
()
❯ echo "POP02\xe2\x0b" | hexdump -C
00000000  50 4f 50 30 32 5c 78 65  32 5c 78 30 62 0a        |POP02\xe2\x0b.|
0000000e
                                                                                                                                                                                                                      ❯ printf "POP02\xe2\x0b" | hexdump -C
00000000  50 4f 50 30 32 e2 0b                              |POP02..|
00000007
alx777 ★★
()

Во-первых есть встроенные команды shell-а и есть бинарники. И это разный код. /usr/bin/bash -c 'echo hi' и /usr/bin/echo hi это разный код. То же касается printf.

Во-вторых printf как правило интерпретирует эскейп-последовательности, а echo не интерпретирует. Но в zsh интерпретирует. Также echo добавляет символ перевода строки в конце, а printf нет.

В-третьих у echo могут быть опции -n чтобы не добавлять символ перевода строки в конца и -e чтобы интерпретировать слеши. А могут и не быть, см. первый пункт. Конечно же эскейп-последовательности в общем случае у каждой реализации могут быть свои, хотя, думаю, можно рассчитывать, что \xHH будет работать везде.

Вот пример из моего терминала, думаю, поймёшь, что всё это значит.

% echo '\xE2' | hexdump -C
00000000  e2 0a                                             |..|
00000002

% /usr/bin/echo '\xE2' | hexdump -C
00000000  5c 78 45 32 0a                                    |\xE2.|
00000005

% /usr/bin/echo -e '\xE2' | hexdump -C
00000000  e2 0a                                             |..|
00000002

% /usr/bin/printf '\xE2' | hexdump -C
00000000  e2                                                |.|
00000001
vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

Резюмируя - вероятно для твоей задачи хватит echo -ne это работает в /usr/bin/echo от coreutils, во встроенном echo bash, zsh и в busybox.

vbr ★★★★★
()
Последнее исправление: vbr (всего исправлений: 1)
Ответ на: комментарий от vbr

в теме сделано решение надзадачи «объяснить юзеру то, что не прочитал описание функций» :)

pfg ★★★★★
()
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.