Любая программа — это автомат, предназначенный для обработки данных: получая на вход одну информацию, они в результате работы выдают некоторую другую. Хотя входящая и/или выходящая информация может быть и нулевой, т. е. попросту отсутствовать. Те данные, которые передаются программе для обработки — это её ввод, то, что она выдаёт в результате работы — вывод. Организация ввода и вывода для каждой программы — это задача операционной системы.
Каждая программа работает с данными определённого типа: текстовыми, графическими, звуковыми и т. п. Как, наверное, уже стало понятно из предыдущих лекций, основной интерфейс управления системой в Linux — это терминал, который предназначен для передачи текстовой информации от пользователя системе и обратно (см. лекцию Терминал и командная строка). Поскольку ввести с терминала и вывести на терминал можно только текстовую информацию, то ввод и вывод программ, связанных с терминалом, тоже должен быть текстовым.
Т. е. в первую очередь командной оболочки и её процессов-потомков, см. лекцию Доступ процессов к файлам и каталогам.
Однако необходимость оперировать с текстовыми данными не ограничивает возможности управления системой, а, наоборот, расширяет их. Человек может прочитать вывод любой программы и разобраться, что происходит в системе, а разные программы оказываются совместимыми между собой, поскольку использут один и тот же вид представления данных — текстовый. Возможностям, которые даёт Linux при работе с данными в текстовой форме, и посвящена данная лекция.
«Текстовость» данных — всего лишь договорённость об их формате. Никто не мешает выводить на экран нетекстовый файл, однако пользы в том будет мало. Во-первых, раз уж файл содержит не текст, то не предполагается, что человек сможет что-либо понять из его содержимого. Во-вторых, если в нетекстовых данных, выводимых на терминал, случайно встретится управляющая последовательность, терминал её выполнит. Например, если в скомпилированной программе записано число 1528515121
, оно представлено в виде четырёх байтов: 27
, 91
, 49
и 74
. Соответствующий им текст состоит из четырёх символов ASCII: «ESC
», «[
», «1
» и «J
», и при выводе файла на виртуальную консоль Linux в этом месте выполнится очистка экрана, так как «^[[1J
» — именно такая управляющая последовательность для виртуальной консоли. Не все управляющие последовательности столь безобидны, поэтому использовать нетекстовые данные в качестве текстов не рекомендуется.
Что же делать, если содержимое нетекстового файла всё-таки желательно просмотреть (то есть превратить в текст)? Можно воспользоваться программой hexdump
, которая выдаёт содержимое файла в виде шестнадцатеричных ASCII-кодов, или strings
, которая показывает только те части файла, что могут быть представлены в виде текста:
[methody@localhost methody]$ hexdump -C /bin/cat | less
00000000 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 |.ELF............|
00000010 02 00 03 00 01 00 00 00 90 8b 04 08 34 00 00 00 |............4...|
00000020 e0 3a 00 00 00 00 00 00 34 00 20 00 07 00 28 00 |Ю:......4. ...(.|
. . .
00000100 00 00 00 00 00 00 00 00 00 00 00 00 06 00 00 00 |................|
00000110 04 00 00 00 2f 6c 69 62 2f 6c 64 2d 6c 69 6e 75 |..../lib/ld-linu|
00000120 78 2e 73 6f 2e 32 00 00 04 00 00 00 10 00 00 00 |x.so.2..........|
00000130 01 00 00 00 47 4e 55 00 00 00 00 00 02 00 00 00 |....GNU.........|
. . .
[methody@localhost methody]$ strings /bin/cat | less
/lib/ld-linux.so.2
_Jv_RegisterClasses
__gmon_start__
libc.so.6
stdout
. . .
[methody@localhost methody]$ strings -n3 /bin/cat | less
/lib/ld-linux.so.2
GNU
_Jv_RegisterClasses
__gmon_start__
libc.so.6
stdout
. . .
.
Пример 1. Использование hexdump
и strings
В примере Мефодий, зная заранее, что текста будет выдано много, воспользовался конвейером «| less
», описанным в разделе Pipeline..Конвейер. С ключом «-C
» утилита hexdump
выводит в правой стороне экрана текстовое представление данных, заменяя непечатные символы точками (чтобы среди выводимого текста не встретилось управляющей последовательности). Мефодий заметил, что strings
«не нашла» в файле /bin/cat
явно текстовых подстрок «ELF
» и «GNU
»: первая из них — вообще не текст (перед ней стоит непечатный символ с кодом 7f
, а после — символ с кодом 1
), а вторая — слишком короткая, хоть и ограничена символами с кодом 0
, как это и полагается строке в скомпилированной программе. Наименьшая длина строки передаётся strings
ключом «-n
».