Поскольку компилятор, ассемблер и загрузчик являются инструментами режима пользователя, изменить со временем по мере необходимости форматы объектных файлов (сравнительно) просто; надо только «научить» ядро новому формату, и он может быть использован. Часть ядра, загружающая исполняемые файлы, относительно невелика, и это не является невозможной задачей. Поэтому форматы файлов Unix развиваются с течением времени. Первоначальный формат был известен как a.out (Assembler OUTput — вывод сборщика). Следующий формат, до сих пор использующийся в некоторых коммерческих системах, известен как COFF (Common Object File Format — общий формат объектных файлов), а современный, наиболее широко использующийся формат — ELF (Extensible Linking Format — открытый формат компоновки). Современные системы GNU/Linux используют ELF.
Ядро распознает, что исполняемый файл содержит двоичный объектный код, проверяя первые несколько байтов файла на предмет совпадения со специальными магическими числами . Это последовательности двух или четырех байтов, которые ядро распознает в качестве специальных. Для обратной совместимости современные Unix-системы распознают несколько форматов. Файлы ELF начинаются с четырех символов « \177ELF».
Помимо двоичных исполняемых файлов, ядро поддерживает также исполняемые сценарии (скрипты) . Такой файл также начинается с магического числа: в этом случае, это два обычных символа # !. Сценарий является программой, исполняемой интерпретатором, таким, как командный процессор, awk, Perl, Python или Tcl. Строка, начинающаяся с #!, предоставляет полный путь к интерпретатору и один необязательный аргумент:
#! /bin/awk -f
BEGIN {print "hello, world"}
Предположим, указанное содержимое располагается в файле hello.awkи этот файл исполняемый. Когда вы набираете ' hello.awk', ядро запускает программу, как если бы вы напечатали ' /bin/awk -f hello.awk'. Любые дополнительные аргументы командной строки также передаются программе. В этом случае, awkзапускает программу и отображает общеизвестное сообщение hello, world.
Механизм с использованием #!является элегантным способом скрыть различие между двоичными исполняемыми файлами и сценариями. Если hello.awkпереименовать просто в hello, пользователь, набирающий ' hello', не сможет сказать (и, конечно, не должен знать), что helloне является двоичной исполняемой программой.
Одним из самых замечательных новшеств Unix было объединение файлового ввода- вывода и ввода-вывода от устройств. [14] Эта особенность впервые появилась в Multics, но Multics никогда широко не использовался — Примеч. автора .
Устройства выглядят в файловой системе как файлы, для доступа к ним используются обычные права доступа, а для их открытия, чтения, записи и закрытия используются те же самые системные вызовы ввода-вывода. Вся «магия», заставляющая устройства выглядеть подобно файлам, скрыта в ядре. Это просто другой аспект движущего принципа простоты в действии, мы можем выразить это как никаких частных случаев для кода пользователя .
В повседневной практике, в частности, на уровне оболочки, часто появляются два устройства: /dev/nullи /dev/tty.
/dev/nullявляется «битоприемником». Все данные, посылаемые /dev/null, уничтожаются операционной системой, а все попытки прочесть отсюда немедленно возвращают конец файла (EOF).
/dev/ttyявляется текущим управляющим терминалом процесса — тем, который он слушает, когда пользователь набирает символ прерывания (обычно CTRL-C) или выполняет управление заданием (CTRL-Z).
Системы GNU/Linux и многие современные системы Unix предоставляют устройства /dev/stdin, /dev/stdoutи /dev/stderr, которые дают возможность указать открытые файлы, которые каждый процесс наследует при своем запуске.
Другие устройства представляют реальное оборудование, такое, как ленточные и дисковые приводы, приводы CD-ROM и последовательные порты. Имеются также программные устройства, такие, как псевдотерминалы, которые используются для сетевых входов в систему и систем управления окнами, /dev/consoleпредставляет системную консоль, особое аппаратное устройство мини-компьютеров. В современных компьютерах /dev/consoleпредставлен экраном и клавиатурой, но это может быть также и последовательный порт
К сожалению, соглашения по именованию устройств не стандартизированы, и каждая операционная система использует для лент, дисков и т.п. собственные имена. (К счастью, это не представляет проблемы для того, что мы рассматриваем в данной книге.) Устройства имеют в выводе ' ls -l' в качестве первого символа bили с.
Читать дальше