16.1. С помощью команды exec

Команда 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

Powered by Drupal — Design by drupal.mensh.ru.