В Linux (и Unix в целом) у каждого процесса есть три файловых дескриптора по умолчанию:
- fd # 0 Представляет стандартный ввод процесса
- fd # 1 Представляет стандартвывод процесса
- fd # 2 Представляет стандартную ошибку процесса
Обычно при запуске простой программы эти файловые дескрипторы по умолчанию настраиваются следующим образом:
- вход по умолчанию считывается с клавиатуры
- Стандартный выход настроен для монитора
- Стандартная ошибка настроена также для монитора
Bash предоставляет несколько операторов для изменения этого поведения (посмотрите на операторы>, >> и <, например).Таким образом, вы можете перенаправить вывод на что-то, отличное от стандартного вывода, или прочитать ваш ввод из другого потока, отличного от клавиатуры.Особенно интересен случай, когда две программы <em>взаимодействуют таким образом, что одна использует выходные данные другой в качестве входных данных.Чтобы упростить эту совместную работу, Bash предоставляет трубочному оператору |
.Обратите внимание на использование сотрудничества вместо цепочки .Я избегал использования этого термина, так как на самом деле канал не является последовательным .Обычная командная строка с конвейерами имеет следующий аспект:
> program_1 | program_2 | ... | program_n
Приведенная выше командная строка немного вводит в заблуждение: пользователь может подумать, что program_2 получает свой ввод после завершения выполнения program_1, что не является правильным,Фактически, bash запускает ALL программ параллельно и настраивает входы-выходы соответственно, так что каждая программа получает свой вход от предыдущей и передает свой вывод следующей (в командной строке).установленный порядок).
Ниже приведен простой пример из Создание канала в C создания канала между родительским и дочерним процессами.Важной частью является вызов функции pipe () и то, как родитель закрывает fd 1 (сторона записи), и как дочерний элемент закрывает fd 1 (сторона записи).Обратите внимание, что канал является однонаправленным каналом связи.Таким образом, данные могут передаваться только в одном направлении: fd 1 в направлении fd [0].За дополнительной информацией обращайтесь к странице справочника pipe ().
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
int main(void)
{
int fd[2], nbytes;
pid_t childpid;
char string[] = "Hello, world!\n";
char readbuffer[80];
pipe(fd);
if((childpid = fork()) == -1)
{
perror("fork");
exit(1);
}
if(childpid == 0)
{
/* Child process closes up input side of pipe */
close(fd[0]);
/* Send "string" through the output side of pipe */
write(fd[1], string, (strlen(string)+1));
exit(0);
}
else
{
/* Parent process closes up output side of pipe */
close(fd[1]);
/* Read in a string from the pipe */
nbytes = read(fd[0], readbuffer, sizeof(readbuffer));
printf("Received string: %s", readbuffer);
}
return(0);
}
Последнее, но не менее важное, если у вас есть командная строка в форме:
> program_1 | program_2 | program_3
ReturnКод всей строки установлен на команду last .В этом случае программа_3.Если вы хотите получить промежуточный код возврата, вы должны установить pipefail или получить его из PIPESTATUS .