Архитектура Unix

       

. Основной цикл программы shell (продолжение)



Рисунок 7.28. Основной цикл программы 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); }


Если процесс запускается асинхронно (на фоне основной программы), как в следующем примере

nroff -mm bigdocument &

shell анализирует наличие символа амперсанд (&) и заносит результат проверки во внутреннюю переменную amper. В конце основного цикла shell обращается к этой переменной и, если обнаруживает в ней признак наличия символа, не выполняет функцию wait, а тут же повторяет цикл считывания следующей команды.

Из рисунка видно, что процесс-потомок по завершении функции fork получает доступ к командной строке, принятой shell'ом. Для того, чтобы переадресовать стандартный вывод в файл, как в следующем примере

nroff -mm bigdocument > output

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



Содержание раздела