В упражнении 13.4 приведена программа popen4.c, которую можно использовать для демонстрации поведения popen
popen, применив команду cat к файлам и затем пересылая по каналу вывод в команду wc -l, которая считает количество строк. В командной строке эквивалентная команда выглядит следующим образом:$ cat popen*.c | wc -l
На самом деле wc -l popen*.c
popenЭта программа применяет в точности предыдущую команду, но с помощью popen
#include
#include
#include
#include
int main() {
FILE *read_fp;
char buffer[BUFSIZ +1];
int chars_read;
memset(buffer, '\0', sizeof(buffer));
read_fp = popen("cat popen*.с | wc -l", "r");
if (read_fp != NULL) {
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
while (chars_read > 0) {
buffer[chars_read - 1] = '\0';
printf("Reading:-\n %s\n", buffer);
chars_read = fread(buffer, sizeof(char), BUFSIZ, read_fp);
}
pclose(read_fp);
exit(EXIT_SUCCESS);
}
exit(EXIT_FAILURE);
}
Выполнив эту программу, вы получите следующий вывод:
$ ./popen4
Reading:-
94
Как это работает
Программа показывает, что вызывается командная оболочка для того, чтобы развернуть popen*.с
popen и заканчивающихся .с, а также для обработки символа канала (|) и отправки вывода команды cat в команду wс. Вы вызываете командную оболочку, программы cat и wc и задаете перенаправление — все в одном вызове popen. Программа, вызвавшая команду, видит только заключительный вывод.Вызов
Вы познакомились с высокоуровневой функцией popen
pipe. Она предоставляет средства передачи данных между двумя программами без накладных расходов на вызов командной оболочки для интерпретации запрашиваемой команды. Эта функция также позволит вам лучше управлять чтением и записью данных.У функции pipe
#include
int pipe(int file_descriptor[2]);
Функции pipe
errno для указания причины сбоя. В интерактивном справочном руководстве Linux на странице, посвященной функций pipe (в разделе 2 руководства), определены следующие ошибки:□ EMFILE
□ ENFILE
□ EFAULT
Два возвращаемых файловых дескриптора подсоединяются специальным образом. Любые данные, записанные в file_descriptor[1]
file_descriptor[0]. Данные обрабатываются по алгоритму1, 2, 3 в file_descriptor[1], чтение из file_descriptor[0] выполняется в следующем порядке: 1, 2, 3. Этот способ отличается от стека, который функционирует по алгоритмуВажно уяснить, что речь идет о файловых дескрипторах, а не о файловых потоках, поэтому для доступа к данным вы должны применять низкоуровневые системные вызовы read
write вместо библиотечных функций потоков fread и fwrite.В упражнении 13.5 приведена программа pipe1.с, которая использует вызов pipe
pipeСледующий пример — программа pipe1.c. Обратите внимание на массив file_pipes
pipe как параметр.#include
#include
#include
#include
int main() {
int data_processed;