Обычно родительский процесс ожидает до концов дочернего процесса путем вызова waitpid
. Родительский процесс получает PID процесса от fork
.
Это означает, что ребенок никогда не предупреждает о родительском процессе всегда, что он вышел или что произошло. Это сделано системой а не дочерним процессом.
Если Вы говорите о выводе программы, родитель обычно никогда не получает вывод дочернего процесса, если это не обеспечило fds. Это также означает, что дочерний процесс печатает вывод а не родительский процесс. Родительский процесс просто получает информацию о состоянии процесса (для получения дополнительной информации посмотрите макросы в waitpid
страница справочника)
ls
произведет то, что это должно произвести на его стандартном выводе. Чтобы сделать это, это звонит write
системный вызов, что-то как:
write(1, "file1 file2...\n", 16)
(или более вероятно это звонит libc
функции как printf
или fwrite
это в конечном счете делает write()
системный вызов)
Это предполагает что дескриптор файла 1
(stdout условно), был уже открыт и указывает на что-то. На самом деле, ls
действительно проверяет ли его дескриптор файла 1 точка к терминалу или чему-то еще. Если это не указывает на терминал, это делает вместо этого:
write(1, "file1\nfile2...\n", 15)
Таким образом, это пишет один файл на строку, когда вывод не переходит к терминалу.
Когда Вы пишете:
ls file1 file2
ls
дескриптор файла 1 укажет на тот же ресурс как fd 1 оболочки (так, например, если это была интерактивная оболочка, запущенная xterm
, это укажет на устройство псевдотерминала, которым управляет xterm). Оболочка не делает ничего специального, она наследована на fork
и потому что O_CLOEXEC
флаг обычно является не набором дескриптора файла, он сохраняется на execve
.
Если Вы пишете:
var=$(ls file1 file2)
Оболочка создает канал, и присваивает fd 1 дочернего процесса к концу записи того канала и читает другой конец канала для заполнения var
переменная.
Это волшебно не сделано на выход, это просто сделано как часть задания процесса. Это независимо от любого другого действия оболочки. ls
просто другой процесс с fd
1 соединенный к некоторому ресурсу как терминал, в то время как оболочка является другим процессом занятое выполнение a waitpid()
.
Что можно найти, хотя это, когда stdout не является терминалом, ls
буферизует его вывод и только звонил бы write()
когда достаточно данных (достаточно являющееся несколькими килобайтами) было накоплено, или это закрывает свой вывод, или это выходит. Так, в том отношении Вы найдете write
сделан после выхода, но только как часть flushing
из буферов, который делается теми библиотеками I/O.
Если exec(3)
успешно выполняется, программа, которая звонила, это больше не. Это заменяется программой exec
редактор новое выполнение программы наследовал среду, в особенности открытые файлы, оригинала.
fork(3)
s, и ребенок затем exec(3)
s ls
. В то время как ls
выполнения, это - дочерний процесс, который принял дочернюю оболочку. Ребенок ls
записи непосредственно на экран, в то время как родительский процесс wait(2)
s, чтобы ребенок закончил перед возобновлением. Первая вещь, которую делает родитель, распечатать подсказку снова.
– vonbrand
14.03.2013, 20:37
|
, оболочка не сделает этого.
– vonbrand
14.03.2013, 20:52