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)
Ответ на: комментарий от windows10

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

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

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

$ echo "$(printf "POP02\xe2\x0b")"
POP02�
neumond ★★
()

Во-первых есть встроенные команды 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)