Один конец канала и считали и пишут fd?

что относительно

fgrep <pattern> `cat file_list.txt`

обратите внимание для помещения корректных кавычек 'и не' - если я понял то, что Вы хотите сделать

4
30.03.2013, 12:50
3 ответа

Да, канал, сделанный с каналом (), имеет два дескрипторов файлов. fd[0] для чтения и fd[1] для записи.

Нет, Вы не должны закрывать ни один конец канала, он может использоваться для двунаправленной связи.

Править: в комментариях Вы хотите знать, как это касается ls | less, таким образом, я объясню что также:

Ваша оболочка имеет три открытых дескрипторов файлов: 0 (stdin), 1 (stdout) и 2 (stderr). Когда оболочка выполняет команду, она делает что-то вроде этого (я упростил ее немного:

pid = fork();
if(pid == 0) {
    /* I am the child */
    execve(...); /* Whatever the user asked for */
}
else {
    waitpid(pid); /* Wait for child to complete */
}

Дескрипторы файлов 0, 1 и 2 наследованы ребенком, таким образом, ввод/вывод работает как ожидалось. Если Вы делаете ls | pipe, что-то немного отличающееся, оказывается, делает перенаправление:

int pipe[2];
pipe(pipe, 0);

pid1 = fork();
if(pid1 == 0) {
    /* This is ls, we need to remap stdout to the pipe. We don't care about reading from the pipe */
    close(pipe[0]);
    close(1);
    dup2(pipe[1], 1);
    execve(...);
}
else {
    pid2 = fork();
    if(pid2 == 0) {
        /* This is less, it reads from the pipe */
        close(pipe[1]);
        close(0);
        dup2(pipe[0], 0);
        execve(...);
    }
    else {
        waitpid(pid1);
        waitpid(pid2);
    }
}

Таким образом, оболочка создает канал, ветвления, и прежде, чем выполниться это повторно отображает канал на stdin или stdout дочерних процессов, делая поток данных из процесса один для обработки 2. Поскольку каналы оболочки не двунаправлены, они только используют один конец канала и закрывают другой конец (он на самом деле закрывает другой конец также после дублирования filedescriptor к stdin или stdout).

6
27.01.2020, 20:48

Это - сводка разговор чата Dennis, и я имел, упрощенный поэтому даже, другие новички могут использовать его. При выполнении ls | less:

  1. Оболочка удара является родительским процессом, который имеет fd[0], fd[1], и fd[2].
  2. pipe() назван родителем, и он создает канал, который является только буфером для размещения данных, и он имеет дескриптор файла в каждом конце, один для чтения и один для записи.
  3. Дочерний процесс наследовал весь открытый fds; 0, 1, и 2, а также два для канала. Таким образом ls имеет его собственную копию буфера с fd[0] и fd[1], но они оба указывают на тот же канал fds от bash. В первом дочернем процессе, ls выполняется и теперь мы должны повторно отобразить вывод на конец записи канала (fd[1]) и затем к консоли. Так close(1) и dup(fd[1]) сделает переотображение. close(1) только влияние ls дочерний процесс, не bash родитель. Теперь вывод ls будет направлен к fd[1] запишите конец канала ребенку. fd[0] все еще конец чтения, и мы не хотим данные, считанные ls с самостоятельно, таким образом, мы все еще должны закрыть тот конец close(fd[0]). Снова, это только окружает дескриптор файла ls, нет bash.
  4. Мы снова ветвление для создания дочернего процесса less, который наследовал дескрипторы файлов канала. Вход к less потребности читать из буфера, таким образом, мы используем fd[0]. С тех пор fd[0] больше не stdin, мы должны повторно отобразить его, таким образом, мы close(0) и dup(fd[0]). Теперь fd[0] укажет на stdin, таким образом, вход здесь является выводом ls. less использование fd[0] для чтения и завершений конец записи fd[1] как less хочет предотвратить данные, считанные его записью с того, чтобы быть выписанным снова
5
27.01.2020, 20:48
  • 1
    Хорошая сводка. Я очистил комментарии к исходной простофиле –  Michael Mrozek♦ 30.03.2013, 20:36
  • 2
    Не был Должен less будьте разветвлены прежде ls? запись в канал вызывает ошибку, когда другой конец закрывается. –  qdii 12.05.2013, 16:33

Вы должны close fd[1] в родителе перед вызовом fork() для меньшего количества команды иначе less команда ожидает бесконечно входа

-1
27.01.2020, 20:48

Теги

Похожие вопросы