Книга: Основы программирования в Linux

Перенаправление ввода и вывода

Перенаправление ввода и вывода

Вы можете применить ваши знания о процессах для изменения поведения программ, используя тот факт, что открытые файловые дескрипторы сохраняются вызовами fork и exec. Следующий пример из упражнения 11.6 содержит программу-фильтр, которая читает из стандартного ввода и пишет в свой стандартный вывод, выполняя при этом некоторое полезное преобразование.

Далее приведена программа очень простой фильтрации upper.c, которая читает ввод и преобразует строчные буквы в прописные:

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int main() {
 int ch;
 while ((ch = getchar()) != EOF) {
  putchar(toupper(ch));
 }
 exit(0);
}

Когда вы выполните программу, она сделает то, что и ожидалось:

$ ./upper
hello THERE
HELLO THERE
^D
$

Вы, конечно, можете применить ее для преобразования символов файла, используя перенаправление, применяемое командной оболочкой:

$ cat file.txt
this is the file, file.txt, it is all lower case.
$ ./upper < file.txt
THIS IS THE FILE, FILE.TXT, IT IS ALL LOWER CASE.

Что если вы хотите применить этот фильтр из другой программы? Программа useupper.c принимает имя файла как аргумент и откликается сообщением об ошибке при некорректном вызове:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
 char *filename;
 if (argc != 2) {
  fprintf (stderr, "usage: useupper filen");
  exit(1);
 }
 filename = argv[1];

Вы повторно открываете стандартный ввод, снова при этом проверяете наличие любых ошибок, а затем применяете функцию execl для вызова программы upper:

 if (!freopen(filename, "r", stdin)) {
  fprintf(stderr, "could not redirect stdin from file %sn", filename);
  exit(2);
 }
 execl("./upper", "upper", 0);

He забудьте, что execl заменяет текущий процесс, если ошибок нет, оставшиеся строки не выполняются.

 perror("could not exec ./upper");
 exit(3);
}

Как это работает

Когда вы выполняете эту программу, ей можно передать файл для преобразования в прописные буквы. Работа делается программой upper, которая не обрабатывает аргументы с именами файлов. Обратите внимание на то, что вам не нужен исходный код программы upper; таким способом можно запустить любую исполняемую программу.

$ ./useupper file.txt
THIS IS THE FILE, FILE.TXT, IT IS ALL LOWER CASE.

Программа useupper применяет freopen для закрытия стандартного ввода и связывания потока файла с файлом, заданным как аргумент программы. Затем она вызывает execl, чтобы заменить код выполняемого процесса кодом программы upper. Поскольку файловые дескрипторы сохраняются, пройдя сквозь вызов execl, программа upper выполняется так же, как при вводе ее в строке командной оболочки

$ ./upper < file.txt

Оглавление книги


Генерация: 0.643. Запросов К БД/Cache: 2 / 0
поделиться
Вверх Вниз