Когда я преобразовывал свои комментарии в ответ, я протестировал предлагаемое изменение, и оно не устранило проблему. Одно исправление, которое должно сработать, - это добавить ; exit
в конце строки, хотя это равносильно измене. Однако тестирование, которое также показывает, что оно не заканчивается; это как если бы ls
не заканчивался.
Я пошел в другой терминал, чтобы посмотреть, были ли еще процессы для ls
или pipe97
(мое имя для вашего кода); они не были.
- Попробуйте набрать
ps
для вашего «зависшего» процесса.
Вы должны получить нормальный вывод и ваше приглашение.
Поскольку родитель не ждет выхода ребенка, подсказка теряется где-то в выводе из ls
(который довольно длинный и генерируется довольно медленно). Перенаправьте вывод на /dev/null
, и вы увидите приглашение.
- Лучшим решением, вероятно, является добавление цикла
wait()
в родительский процесс, поэтому он не завершается до тех пор, пока дочерний процесс не сделает.
#include <sys/wait.h>
…
int corpse;
int status;
while ((corpse = wait(&status)) > 0)
;
Во время отладки вы можете печатать corpse
и status
, чтобы видеть, что происходит.
Я заметил, что этот комментарий (без преамбулы) остается в силе:
… close(fd[0]);
должен быть перед execl()
- запомните, если он успешен, execl()
никогда не возвращается (он возвращается только при ошибке). Возможно, вы должны иметь отчет об ошибке и exit(1);
или аналогичный после execl()
; на данный момент вы сообщаете об успехе даже при неудаче.
Комментарий Rule of Thumb сам по себе действителен, но на самом деле он неприменим к этому коду - дескрипторы незакрытых каналов не вызывают проблем, даже если один дескриптор канала должен был быть закрыт не был закрыт.