TGViewer
Bash Days | Linux | DevOps Bash Days | Linux | DevOps @bashdays · 23.6K subscribers
Post #439 15.5K
Грустно признавать, но сегодня под вечер будем ковыряться в кишочках и дебажить аномалию. Но оно того стоит!

Выполняем команду:

echo Shs | base64 -d  
Jase64: invalid input


И наблюдаем аномалию в названии утилиты: Jase64.

Из команды понятно, что утилита base64 при декодировании обнаружила ошибку в данных. Ошибка — не корректная длина закодированного текста (invalid input).

Но чо за херня с Jase64? Новая попа-группа Юры Шильникова-Томатного? Должно же быть Base64?

Если что-то пошло попесде, нам поможет «страус». Расчехляем strace.


Давай посмотрим что и куда пишет base64. Перенаправляем стандартные потоки вывода и ошибки в устройство /dev/null. Дополнительно говорим «страусу», чтобы выводил системные вызовы write.

Запускаем кишку:

с запущенной кишкой, обычно к практологу

LC_ALL=C strace -Yqqqyfe write -P /dev/null --signal=none bash -c 'echo Shs | base64 -d &>/dev/null'


Кратенько по ключам:

LC_ALL = страхуемся
Y = чекаем вызовы ввода-вывода
qqq = меньше мусора
y = показываем пути к файлам
f = чекаем дочерние процессы
e = выбираем вызовы write
P = ограничение трассировки
signals = не следим за сигналами

После запуска получаем:

[<base64>] write(1</dev/null>, "J\33", 2) = 2
[<base64>] write(2</dev/null>, "base64: ", 8) = 8
[<base64>] write(2</dev/null>, "invalid input", 13) = 13
[<base64>] write(2</dev/null>, "\n", 1) = 1


Уже поинтереснее. Разбираем.

- В первой строке происходит запись части декодированного текста в стандартный вывод (дескриптор 1).

- В следующих двух строках, в стандартный поток ошибок пишется имя утилиты и ошибка (дескриптор 2).

- Ну и последняя строка, запись новой строки.

Теперь снова смотрим первую строку и видим что системный вызов write пишет букву «J» и какой-то магический символ 33.

✔️ «Страус» по умолчанию выводит числовые значения непечатных символов в восьмеричной системе счисления. То есть 033 будет соответствовать символу ESC в кодировке ASCII.

И чо? А то, что для драйвера терминала, этот символ означает начало управляемой последовательности. Вот это поворот!

Скучная теория

Драйвер терминала это код, который распознает управляющие последовательности и интерпретирует их в действия. Например, перемещает курсор.

В моем случае, драйвер это эмулятор терминала (Terminal). А еще есть код в пространстве ядра, который реализует специальные устройства. И этот код может модифицировать данные проходящие через эту линию связи.

Схема терминала:

Bash write stdout -> /dev/pts/number Kernel_Space <- /dev/ptmx Terminal read

Terminal write -> /dev/ptmx Kernel_Space <- /dev/pts/number Bash read


Bash read это чтение команды, или сочетания клавиш например для редактирования строки.

Возвращаемся к Jase64

Для начала исключаем пространство ядра (Kernel_Space) и проводим проверку данных, которые поступили на устройство читаемое эмулятором терминала.

Видим что на устройстве эмулятора Terminal, данные пришли без искажений. Подозреваемым остается драйвер терминала.

write(30</dev/ptmx>, "\33[200~echo Shs | base64 -d \33[201"..., 33) = 33


Как это 👆 получить, я рассказал утром в этом посте.


И происходит следующее. Эмулятор терминала получив символ «J» отображает его, но потом натыкается на специальный символ ESC начало управляющей последовательности и слово base64.

Символ «b» распознаётся как часть управляющей последовательности и этот символ не отображается.

Многие терминалы не имеют никаких действий связанных с данной последовательностью «ESCb» и она просто отбрасывается.

Ниже пару примеров, когда часть последующего ввода распознаётся как завершение управляющей последовательности.

echo -ne 'J\033' ; sleep 3 ; echo base64 >&2  
echo -ne 'J\033[64' ; sleep 3 ; echo bashdays >&2


Вот такие вот приколы, вот такие вот кишочки. Нельзя просто так взять и насыпать в терминал всё что тебе захочется.

Если после каких-то действий, ты начал замечать аномалии, выполни команду reset и всё встанет на свои места.

Хорошая статья: The TTY demystified.

И да, всем отличных предстоящих выходных, берегите себя ❤️

Не забываем подписываться на пиздатые тулзы.


tags: #linux #bash #debug
—
🔔 @bashdays
More from @bashdays
  1. Sep 30, 2026↗️ Для всех, кто строит 15 октября Cloud․ru соберет инженеров, которые строят и эксплуатир…
  2. Sep 29, 2026Самый жаркий холивар в команде — это не systemd, а какие заказать роллы на всю команду. Од…
  3. Sep 24, 2026Post #1565
  4. Sep 23, 2026Здрасти приехали, решил я в кой-то веке воспользоваться услугами Codex, создал аккаунт, по…
  5. Sep 22, 2026Всем привет, с вами TagdTagd. Сегодня опять поднимем тему архивов, но немного с другой сто…
  6. Sep 15, 2026Всем привет, с вами TagdTagd. И это вторая часть. Практическая. С первой частью можешь озн…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →