5. Что происходит, когда вы запускаете на выполнение программы в командном интерпретаторе shell?

Shell в Unix интерпретирует вводимые вами команды; он назван shell (раковина, скорлупа, оболочка), потому что обёртывает и скрывает от пользователя ядро операционной системы. Это важная особенность Unix: shell и ядро (kernel) — разные программы, общающиеся посредством системных вызовов. Это делает возможным существование множества shells, удовлетворяющих разным вкусам в интерфейсе.

Обычно после входа в систему shell выводит приглашение «$» (если вы не изменили его на что-то другое). Вместо обсуждения синтаксиса команд и простых вещей, которые вы видите на экране, мы заглянем за сцену и посмотрим, что же происходит с точки зрения компьютера.

После загрузки системы и прежде чем вы запустили какую-либо программу, ваш компьютер можно представить как место, в котором находится целый зоопарк процессов, каждый из которых ждёт, когда нужно будет что-то сделать. Все они ждут событий (events). Событие $mdash; это, например, нажатие клавиши или движение мышки. Если ваш компьютер подключён к сети, событием может быть пришедший по сети пакет с данными.

Ядро — один из этих процессов. Это особый процесс, потому что он контролирует другие пользовательские процессы (user processes), и обычно это единственный процесс, имеющий непосредственный доступ к аппаратным средствам компьютера. В действительности, пользовательские процессы делают запросы к ядру, когда им нужно получить ввод с клавиатуры, вывести данные на экран, прочитать или записать на диск, и вообще сделать что-либо, кроме перебирания битов в памяти. Эти запросы известны как системные вызовы (system calls).

Обычно весь ввод/вывод (I/O) идёт через ядро, и оно таким образом может планировать операции и предотвращать конфликты между процессами. Нескольким специальным пользовательским процессам дозволено обходить ядро, обычно для прямого доступа к портам ввода/вывода (I/O ports). Наиболее яркий пример такого процесса — X-сервер (программа, которая управляет запросами других программ на доступ к работе с графическим экраном на большинстве машин с Unix). Но мы пока не добрались до X-сервера, и смотрим на приглашение shell, выведенное на экран.

Shell — это обычный пользовательский процесс, и ничего в нем особенного нет. Он ожидает нажатий на клавиши, прослушивая (через ядро) порт ввода/вывода клавиатуры. Как только ядро видит их, shell отражает их на экране. Когда ядро видит нажатие клавиши «Enter» («Ввод»), оно посылает shell строку набранного вами текста. Shell пытается интерпретировать это как команду.

Скажем, вы набрали «ls» и нажали Enter, чтобы вызвать команду Unix, которая выводит список файлов и каталогов. Shell, используя встроенные в него правила, определяет, что вы хотите выполнить команду, содержащуюся в файле /bin/ls. Shell делает системный вызов к ядру, запрашивающий запуск /bin/ls в качестве нового дочернего процесса (child process), передаёт ему доступ (через ядро) к экрану и клавиатуре. После этого shell отправляется спать, ожидая пока ls закончит свою работу.

Когда /bin/ls закончит, он сообщит об этом ядру через системный вызов exit (выход). Тогда ядро разбудит shell и скажет ему, что можно продолжать работу. Shell снова выведет приглашение и будет ждать получения очередной строки ввода.

Однако, пока выполняется «ls», могут происходить и другие вещи (вывод списка файлов может быть долгим, если их очень много). Вы можете переключится на другую виртуальную консоль, войти там в систему, и запустить, например, игру Quake. Или, предположим, вы подключены к Интернет. Ваша машина в силе отправлять и получать почту, пока работает /bin/ls.