Найти тему
BASH DAYS | Linux Factory

Про управляющие символы в Linux

Когда ты выполняешь команду ls -l, оно выводит тебе на экран список каталогов и файлов. Все это цветное и красивое. Но если сделать так:

ls -l | cat

То по итогу получим просто список каталогов и файлов, без навешанных стилей и красок. Серое и унылое. Куда делись управляющие символы (последовательности), которые всё это раскрашивают?

Да, есть такое. Когда применяешь перенаправленный вывод, управляющие символы куда-то исчезают. Давай разберемся что происходит.

Все предельно просто. В утилитах содержится проверка своего стандартного вывода (stdout), которая не использует некоторые управляющие символы, если stdout не связан с терминалом.

И это вполне логично. Если бы эти управляющие символы передавались следующей команде, в моем случае в cat. То cat бы получил на вход помимо данных, кучу мусора, типа такого:

\e[31mBashdays\e[0m

Теперь полезем в кишки, чтобы лучше понять происходящее.

Запускаем strace:

strace -o output.txt -yf ls -l --color=auto | cat

Тут я указал утилите ls опцию color с аргументом auto. В большинстве случаев из коробки идет alias в котором уже прописана эта опция. Но так, как мы запускаем ls через strace, то существующие алиасы не будут использоваться. Вот лишь по этому и запихиваем все это в одну строку.

-y = отслеживать открытие файлов.
-f = отслеживать все процессы и форки.
-o = пишем выхлоп strace в файл.

Подпишись на BashDays в телеграм



Открываем файл output.txt и смотрим в него пустым взглядом. Но лучше грепаем вызов ioctl:

grep -i "ioctl" output.txt

Получаем несколько строк, в которых видим ошибку:

-1 ENOTTY (Inappropriate ioctl for device)

Это говорит о том, что процесс попытался выполнить операцию ввода-вывода (I/O), которая не поддерживается устройством. Канал просто не поддерживает эту возможность.

Ну и напоследок сделаем инъекцию. В
этом посте можешь еще один пример с инъекцией глянуть. Запускаем:

strace -o /dev/null -fe inject=ioctl:retval=0 ls -l --color=auto | cat -v

Суть такая, если возникает ошибка, то ничего не делаем, а продолжаем работу. Эмулируем ситуацию, когда ioctl вернул статус успеха, а не -1 ENOTTY.

Опция retval=значение, это своего рода фильтр, в моем контексте он будет трассировать только системные вызовы ioctl у которых статус = не успех.

Запустили. Команда отработала, на экране видим список каталогов и файлов с управляющими символами (последовательностями).

drwxr-xr-x ^[[0m^[[01;34m1^[[0m
-rwxr-xr-x ^[[01;32mbash^[[0m
drwxr-xr-x ^[[01;34mbin^[[0m
drwxr-xr-x ^[[01;34mnginx^[[0m


Что и следовало доказать. Ну а если просто хочется протестировать управляющие символы без всяких strace, можно воспользоваться аргументом always и ключом -v для cat.

ls --color=always | cat -v

-v, --show-nonprinting

Вот так вот и живем. Теперь и ты это знаешь. Хорошего всем дня, увидимся!

Рекомендую почитать