Команда exec <filename перенаправляет ввод со stdin на файл. С этого момента весь ввод, вместо stdin (обычно это клавиатура), будет производиться из этого файла. Это дает возможность читать содержимое файла, строку за строкой, и анализировать каждую введенную строку с помощью sed и/или awk.
Пример 16-1. Перенаправление stdin с помощью exec
#!/bin/bash # Перенаправление stdin с помощью 'exec'. exec 6&0 # Связать дескр. #6 со стандартным вводом (stdin). # Сохраняя stdin. exec data-file # stdin заменяется файлом "data-file" read a1 # Читается первая строка из "data-file". read a2 # Читается вторая строка из "data-file." echo echo "Следующие строки были прочитаны из файла." echo "-----------------------------------------" echo $a1 echo $a2 echo; echo; echo exec 0&6 6&- # Восстанавливается stdin из дескр. #6, где он был предварительно сохранен, #+ и дескр. #6 закрывается ( 6&- ) освобождая его для других процессов. # # &6 6&- дает тот же результат. echo -n "Введите строку " read b1 # Теперь функция "read", как и следовало ожидать, принимает данные с обычного stdin. echo "Строка, принятая со stdin." echo "--------------------------" echo "b1 = $b1" echo exit 0
Аналогично, конструкция exec >filename перенаправляет вывод на stdout в заданный файл. После этого, весь вывод от команд, который обычно направляется на stdout, теперь выводится в этот файл.
Пример 16-2. Перенаправление stdout с помощью exec
#!/bin/bash # reassign-stdout.sh LOGFILE=logfile.txt exec 6>&1 # Связать дескр. #6 со stdout. # Сохраняя stdout. exec > $LOGFILE # stdout замещается файлом "logfile.txt". # ----------------------------------------------------------- # # Весь вывод от команд, в данном блоке, записывается в файл $LOGFILE. echo -n "Logfile: " date echo "-------------------------------------" echo echo "Вывод команды \"ls -al\"" echo ls -al echo; echo echo "Вывод команды \"df\"" echo df # ----------------------------------------------------------- # exec 1>&6 6>&- # Восстановить stdout и закрыть дескр. #6. echo echo "== stdout восстановлено в значение по-умолчанию == " echo ls -al echo exit 0
Пример 16-3. Одновременное перенаправление устройств, stdin и stdout, с помощью команды exec
#!/bin/bash # upperconv.sh # Преобразование символов во входном файле в верхний регистр. E_FILE_ACCESS=70 E_WRONG_ARGS=71 if [ ! -r "$1" ] # Файл доступен для чтения? then echo "Невозможно прочитать из заданного файла!" echo "Порядок использования: $0 input-file output-file" exit $E_FILE_ACCESS fi # В случае, если входной файл ($1) не задан #+ код завершения будет этим же. if [ -z "$2" ] then echo "Необходимо задать выходной файл." echo "Порядок использования: $0 input-file output-file" exit $E_WRONG_ARGS fi exec 4&0 exec $1 # Назначить ввод из входного файла. exec 7>&1 exec > $2 # Назначить вывод в выходной файл. # Предполагается, что выходной файл доступен для записи # (добавить проверку?). # ----------------------------------------------- cat - | tr a-z A-Z # Перевод в верхний регистр # ^^^^^ # Чтение со stdin. # ^^^^^^^^^^ # Запись в stdout. # Однако, и stdin и stdout были перенаправлены. # ----------------------------------------------- exec 1>&7 7>&- # Восстановить stdout. exec 0&4 4&- # Восстановить stdin. # После восстановления, следующая строка выводится на stdout, чего и следовало ожидать. echo "Символы из \"$1\" преобразованы в верхний регистр, результат записан в \"$2\"." exit 0