Воспроизвести поведение bash с помощью каналов и бесконечных команд - PullRequest
0 голосов
/ 08 декабря 2018

Я нахожусь в процессе создания оболочки терминала из C (с Bash в качестве ссылки), и мне пришлось столкнуться с конвейерами.
То, как я их сделал, работало с базовыми командами, такими как ls | rev | wc -l
Однако моя программа входит в бесконечный цикл, когда я пытаюсь передать команды, которые никогда не заканчиваются, как эта: base64 /dev/urandom | head -c 1000;Bash этого не делает.
Способ, которым я создал свой конвейер, заставляет мою программу ждать окончания base64, прежде чем вызывать head.
Я не понимаю, когда и как я должен больше ждать и выполнять команды.
Как я могу воспроизвести поведение Bash с помощью таких переданных команд в C?Я совершил простую ошибку или я должен полностью переосмыслить свою систему?

Вот псевдокод, как я выполняю свою команду.В нем отсутствуют детали и безопасность, такие как закрытие труб, но вся идея присутствует.

while (command)
{
    pipe(fd);
    if (!fork())
    {
       dup2();
       execve(command);
    }
    wait();
    command = command->next;
}

1 Ответ

0 голосов
/ 08 декабря 2018

Краткий ответ:

Избавьтесь от wait () для начинающих.

Но это еще не все.Не то чтобы я был экспертом, но из наблюдения за поведением bash я узнал, что все компоненты в конвейере выполняются одновременно параллельно

AFAIK, bash (или, возможно, реализация fifo в ядре) будет генерировать сигналык процессу, когда другой процесс на другой стороне трубы закрыл трубу.'base64 / dev / urandom' завершается, потому что он получил сигнал, когда голова закрылась, это стандартный вывод.

Как вы уже видели, base64 / dev / urandom никогда не заканчивается сам по себе.

В дальнейшем запускайте все процессы, создавая fifo с подключенными stdout и stdin.Я надеюсь, что это приведет вас в правильном направлении.Существует много дискуссий о том, как использовать fifo, так что, надеюсь, это толчок в правильном направлении.

...