Архитектура операционной системы UNIX


         

КОМАНДНЫЙ ПРОЦЕССОР SHELL


Теперь у нас есть достаточно материала, чтобы перейти к объяснению принципов работы командного процессора shell. Сам командный процессор намного сложнее, чем то, что мы о нем здесь будем излагать, однако взаимодействие процессов мы уже можем рассмотреть на примере реальной программы. На приведен фрагмент основного цикла программы shell, демонстрирующий асинхронное выполнение процессов, переназначение вывода и использование каналов.

Shell считывает командную строку из файла стандартного ввода и интерпретирует ее в соответствии с установленным набором правил. Дескрипторы файлов стандартного ввода и стандартного вывода, используемые регистрационным shell'ом, как правило, указывают на терминал, с которого пользователь регистрируется в системе (см. ). Если shell узнает во введенной строке конструкцию собственного командного языка (например, одну из команд cd, for, while и т.п.), он исполняет команду своими силами, не прибегая к созданию новых процессов; в противном случае команда интерпретируется как имя исполняемого файла.

Командные строки простейшего вида содержат имя программы и несколько параметров, например: who grep -n include *.c ls -l

Shell "ветвится" (fork) и порождает новый процесс, который и запускает программу, указанную пользователем в командной строке. Родительский процесс (shell) дожидается завершения потомка и повторяет цикл считывания следующей команды.

if (fork() == 0) { /* первая компонента командной строки */ close(stdout); dup(fildes[1]); close(fildes[1]); close(fildes[0]); /* стандартный вывод направляется в ка- нал */ /* команду исполняет порожденный про- цесс */ execlp(command1,command1,0); } /* вторая компонента командной строки */ close(stdin); dup(fildes[0]); close(fildes[0]); close(fildes[1]); /* стандартный ввод будет производиться из канала */ } execve(command2,command2,0); } /* с этого места продолжается выполнение родительского * процесса... * процесс-родитель ждет завершения выполнения потомка, * если это вытекает из введенной строки * / if (amper == 0) retid = wait(&status); }




Содержание  Назад  Вперед