Мне нужно написать оболочку, которая может запускать трубы. Для команд пример, как ls -l | wc -l
». Я успешно разобраны команды, заданной пользователем, как показано ниже:Трубы, dup2 и exec()
"LS"= firstcmd
"-l"= frsarg
"туалет"= SCMD
«-l» = secarg
Теперь я должен использовать две вилки, так как команды два и труба. Блочный код, который я написал EXEC команду заключается в следующем:
pid_t pid;
int fd[2];
pipe(fd);
pid = fork();
if(pid==0)
{
dup2(fd[WRITE_END], STDOUT_FILENO);
close(fd[READ_END]);
execlp(firstcmd, firstcmd, frsarg, (char*) NULL);
}
else
{
pid=fork();
if(pid==0)
{
dup2(fd[READ_END], STDIN_FILENO);
close(fd[WRITE_END]);
execlp(scmd, scmd, secarg, (char*) NULL);
}
}
Так что, когда я запускаю свою оболочку и я вхожу в команду ls -l | wc -l
(например) результат от Execs не отображается, но shell работает нормально.
Странно, что результат команды отображается только тогда, когда я завершаю свою оболочку с помощью «exit» или «^ C».
Что не так с этим выходом? Почему он не появляется сразу после ввода команды?
Вам необходимо закрыть FD-каналы в родительских процессах. – Barmar
Можете ли вы изменить мой код, чтобы помочь мне понять, что вы имеете в виду, пожалуйста? @Barmar –
** Правило большого пальца **: если вы дублируете один конец трубы на стандартный вход или стандартный вывод, вы должны закрыть оба конца исходного канала перед использованием 'exec *()' функций (или иначе продолжать). Есть исключения; их мало и далеко. Очень редко (на SO и IRL) вы сталкиваетесь с программой, использующей каналы, которые закрывают слишком много дескрипторов; очень часто бывает найти программу, которая не закрывает достаточно дескрипторов. Это особенно часто встречается, если несколько детей и/или несколько труб путают вещи. –