Перейти к основному содержанию
Рецепты Linux

Main navigation

  • Основы
  • Система
  • Команды
  • Программы
  • Дистро
  • Интерфейсы
  • Устройства
  • Доки
User account menu
  • Войти

Строка навигации

  1. Главная
  2. ABS Guide
  3. Часть 3. Углубленный материал
  4. Глава 16. Перенаправление ввода/вывода

16.2. Перенаправление для блоков кода

Блоки кода, такие как циклы while, until и for, условный оператор if/then, так же могут смешиваться с перенаправлением stdin. Даже функции могут использовать эту форму перенаправления (см. Пример 22-10). Оператор перенаправления <, в таких случаях, ставится в конце блока.

Пример 16-4. Перенаправление в цикл while

#!/bin/bash

if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если имя файла не задано.
else
 Filename=$1
fi
# Конструкцию проверки выше, можно заменить следующей строкой (подстановка параметров):
#+ Filename=${1:-names.data}

count=0

echo

while [ "$name" != Smith ] # Почему переменная $name взята в кавычки?
do
 read name # Чтение из $Filename, не со stdin.
 echo $name
 let "count += 1"
done "$Filename" # Перенаправление на ввод из файла $Filename.
# ^^^^^^^^^^^^

echo; echo "Имен прочитано: $count"; echo

# Обратите внимание: в некоторых старых командных интерпретаторах,
#+ перенаправление в циклы приводит к запуску цикла в субоболочке (subshell).
# Таким образом, переменная $count, по окончании цикла, будет содержать 0,
# значение, записанное в нее до входа в цикл.
# Bash и ksh стремятся избежать запуска субоболочки (subshell), если это возможно,
#+ так что этот сценарий, в этих оболочках, работает корректно.
#
# Спасибо Heiner Steven за это примечание.

exit 0

Пример 16-5. Альтернативная форма перенаправления в цикле while

#!/bin/bash

# Это альтернативный вариант предыдущего сценария.

# Предложил: by Heiner Steven
#+ для случаев, когда циклы с перенаправлением
#+ запускаются в субоболочке, из-за чего переменные, устанавливаемые в цикле,
#+ не сохраняют свои значения по завершении цикла.


if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если имя файла не задано.
else
 Filename=$1
fi


exec 3&0 # Сохранить stdin в дескр. 3.
exec 0"$Filename" # Перенаправить stdin.

count=0
echo


while [ "$name" != Smith ]
do
 read name # Прочитать с перенаправленного stdin ($Filename).
 echo $name
 let "count += 1"
done "$Filename" # Цикл читает из файла $Filename.
# ^^^^^^^^^^^^


exec 0&3 # Восстановить stdin.
exec 3&- # Закрыть временный дескриптор 3.

echo; echo "Имен прочитано: $count"; echo

exit 0

Пример 16-6. Перенаправление в цикл until

#!/bin/bash
# То же самое, что и в предыдущем примере, только для цикла "until".

if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если файл не задан.
else
 Filename=$1
fi

# while [ "$name" != Smith ]
until [ "$name" = Smith ] # Проверка != изменена на =.
do
 read name # Чтение из $Filename, не со stdin.
 echo $name
done "$Filename" # Перенаправление на ввод из файла $Filename.
# ^^^^^^^^^^^^

# Результаты получаются теми же, что и в случае с циклом "while", в предыдущем примере.

exit 0

Пример 16-7. Перенаправление в цикл for

#!/bin/bash

if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если файл не задан.
else
 Filename=$1
fi

line_count=`wc $Filename | awk '{ print $1 }'`
# Число строк в файле.
#
# Слишком запутано, тем не менее показывает
#+ возможность перенаправления stdin внутри цикла "for"...
#+ если вы достаточно умны.
#
# Более короткий вариант line_count=$(wc  "$Filename")


for name in `seq $line_count` # "seq" выводит последовательность чисел.
# while [ "$name" != Smith ] -- более запутанно, чем в случае с циклом "while" --
do
 read name # Чтение из файла $Filename, не со stdin.
 echo $name
 if [ "$name" = Smith ]
 then
 break
 fi
done "$Filename" # Перенаправление на ввод из файла $Filename.
# ^^^^^^^^^^^^

exit 0

Предыдущий пример можно модифицировать так, чтобы перенаправить вывод из цикла.

Пример 16-8. Перенаправление устройств (stdin и stdout) в цикле for

#!/bin/bash

if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если файл не задан.
else
 Filename=$1
fi

Savefile=$Filename.new # Имя файла, в котором сохраняются результаты.
FinalName=Jonah # Имя, на котором завершается чтение.

line_count=`wc $Filename | awk '{ print $1 }'` # Число строк в заданном файле.


for name in `seq $line_count`
do
 read name
 echo "$name"
 if [ "$name" = "$FinalName" ]
 then
 break
 fi
done  "$Filename" > "$Savefile" # Перенаправление на ввод из файла $Filename,
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^ и сохранение результатов в файле.

exit 0

Пример 16-9. Перенаправление в конструкции if/then

#!/bin/bash

if [ -z "$1" ]
then
 Filename=names.data # По-умолчанию, если файл не задан.
else
 Filename=$1
fi

TRUE=1

if [ "$TRUE" ] # конструкции "if true" и "if :" тоже вполне допустимы.
then
 read name
 echo $name
fi "$Filename"
# ^^^^^^^^^^^^

# Читает только первую строку из файла.

exit 0

Пример 16-10. Файл с именами "names.data", для примеров выше

Aristotle
Belisarius
Capablanca
Euler
Goethe
Hamurabi
Jonah
Laplace
Maroczy
Purcell
Schmidt
Semmelweiss
Smith
Turing
Venn
Wilson
Znosko-Borowski

# Это файл с именами для примеров
#+ "redir2.sh", "redir3.sh", "redir4.sh", "redir4a.sh", "redir5.sh".

Перенаправление stdout для блока кода, может использоваться для сохранения результатов работы этого блока в файл. См. Пример 3-2.

Встроенный документ -- это особая форма перенаправления для блоков кода.

Перекрёстные ссылки книги для 16.2. Перенаправление для блоков кода

  • 16.1. С помощью команды exec
  • Вверх
  • 16.3. Область применения

Book navigation

  • Содержание
  • Часть 1. Введение
  • Часть 2. Основы
  • Часть 3. Углубленный материал
    • Глава 9. К вопросу о переменных
    • Глава 10. Циклы и ветвления
    • Глава 11. Внутренние команды
    • Глава 12. Внешние команды, программы и утилиты
    • Глава 13. Команды системного администрирования
    • Глава 14. Подстановка команд
    • Глава 15. Арифметические подстановки
    • Глава 16. Перенаправление ввода/вывода
      • 16.1. С помощью команды exec
      • 16.2. Перенаправление для блоков кода
      • 16.3. Область применения
    • Глава 17. Встроенные документы
  • Часть 4. Материал повышенной сложности
  • Глава 35. Замечания и дополнения
  • Библиография
  • Приложение A. Дополнительные примеры сценариев
  • Приложение B. Справочная информация
  • Приложение C. Маленький учебник по Sed и Awk
  • Приложение D. Коды завершения, имеющие предопределенный смысл
  • Приложение E. Подробное введение в операции ввода-вывода и перенаправление ввода-вывода
  • Приложение F. Системные каталоги
  • Приложение G. Локализация
  • Приложение H. История команд
  • Приложение I. Пример файла .bashrc
  • Приложение J. Преобразование пакетных (*.bat) файлов DOS в сценарии командной оболочки
  • Приложение K. Упражнения
  • Приложение L. Хронология
  • Приложение M. Авторские права

Последние материалы

  • Приложение scanimage
    1 day ago
  • Утилита sensors
    5 days ago
  • Сканер Rkhunter
    1 week 5 days ago
  • Программа resize2fs
    2 weeks 3 days ago
  • Аудиопроигрыватель QMMP
    3 weeks 2 days ago
RSS feed

Secondary menu

  • О проекте

© 2008–2025 Олег Меньшенин mensh@yandex.ru