Книга: Основы программирования в 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
- Перенаправление портов
- Перенаправление ввода
- Пример: перенаправление ввода
- Приложение D. Подробное введение в операции ввода-вывода и перенаправление ввода-вывода
- 5.4.3. Перенаправление стандартных потоков ввода, вывода и ошибок
- 5.2. Перенаправление ввода
- Пример 3-1. Вложенные блоки и перенаправление ввода-вывода
- Файловая подсистема
- Синтаксис языка Bourne shell
- Подстановки, выполняемые командным интерпретатором