Перенаправлення вводу-виводу

Матеріал з Вікі ЦДУ
Перейти до: навігація, пошук

Команди і сценарії можуть отримувати вхідні дані двома способами: з стандартного вхідного потоку (пов'язаний з клавіатурою) або з файлу. Аналогичний поділ існує і при виведенні даних: результати роботи команди або сценарію за замовчуванням направляються на екран терміналу, але ожна перенаправляти їх у файл. Якщо в процесі роботи виникають помилки. повідомлення про них може відображаються на екрані, потік помилок также можна переспрямувати у файл.

Розглянемо спочатку кілька команд, з допомогою яких можна організувати ввід/вивід.

Результат виконання команди >>

Команди виведення на стандартний пристрій виводу

Linux надає кілька команд для виведення повідомлень у стандартний потік виводу:

  • echo - Вивести рядок у стандартний потік виводу.
  • printf - Вивести форматований текст у стандартний ппоток виводу.
  • yes - Виводити повторюваний текст у стандартний ппоток виводу.
  • seq - Показує послідовність чисел у стандартний ппоток виводу
  • clear Очистити екран або вікно.

Наприклад, при використанні команди echo якщо вказати керуючий символ \с, то після закінчення виведення не буде здійснено перехід в новий рядок:

$ echo "Як вас звати?\c"

як вас звати?$

Тут $ - символ запрошення.

У рядку також можна обчислювати значення змінних інтерпретатора shell і навіть інших команд. Наприклад, наступна команда про те, який початковий каталог поточного користувача (змінна оточення $HOME) і до якого терміналу він підключений (команда tty укладена в зворотні лапки, щоб інтерпретатор помістив у рядок результат її виконання).

$ echo "Ваш початковий каталог - $HOME, ви підключені до терміналу - `tty` "

Ваш початковий каталог - /home/knoppix, ви підключені до терміналу - /dev/tty1

подвійні лапки у інтерпретаторі shell мають спеціальне призначення, то для того щоб у виводиться рядок включити подвійні "", потрібно скасувати їх спеціальне призначення з допомогою зворотного скісної риски (\). Так скасовується призначення будь-якого спеціального символа.

Наприклад, щоб вивести рядок “/dev/tty1” необхідно виконати:

$echo “\”/dev/tty1\””


Команди зі стандартного вводу пристроїв введення

Команда read читає один рядок з стандартного вхідного потоку і записує її вміст в зазначені змінні. якщо вказівці декількох змінних в першу з них записується перше слово, у другу - друге і т.д. в останню - залишок рядка.

Сценарій викликає окрему команду read для читання кожної змінної.


$ cat test

  1. !/bin/bash

echo “Ім'я: \” read name echo “Прізвище: \c” read surname echo “Ім'я=” $name “Прізвище=” $surname

для виконання цього сценарію необхідно файлу test дати право виконання: chmod 0755 test і запустити його ./test.

Результат виконання: ім'я: Іван прізвище: Петров ім'я=Іван Прізвище=Петров


Стандартні потоки вводу-виводу

Запущена з інтерпретатора командного програма отримує три відкритих потоку вводу/виводу:

- стандартний ввід (sldin)
- стандартний вивід( sldout)
- стандартний висновок помилок (stderr)

По замовчуванню ці потоки асоційовані з терміналом. Тобто будь-яка програма, що не використовує потоки, крім стандартних, буде очікувати введення з клавіатури терміналу, весь висновок цієї програми, включаючи повідомлення про помилки, буде відбуватися на екран терміналу.

При цьому з кожним процесом (командою, сценарієм і т.п.), виконуваних у інтерпретаторі shell, пов'язаний радий відкритих файлів, яких процес допоможе читати свої дані: і в які він може записувати їх. Кожен з цих файлів ідентифікується числом, званим дескриптором файлу, але перші три файлу є потоками введення/виводу за замовчуванням:


Файл Дескриптор Стандартний потік вводу 0 Стандартний потік виводу 1 Стандартний потік помилок 2 Насправді створюється 12 відкритих файлів, але файли з дескрипторами 0, 1 і 2 резервуються для стандартних потоків введення, виводу і помилок. Користувачі можуть також працювати з файлами, які мають дескриптори від 3 до 9 (зарезервовані).

файлу стандартного потоку вводу (sldin) має дескриптор 0. З цього файлу процеси мають свої вхідні дані. По замовчуванню вхідний потік асоційований з клавіатурою (пристрій /dev/tty), але найчастіше він надходить по каналу від пдругих процесів або з звичайного файлу.

Файл стандартного потоку виводу (stdout) має дескриптор 1. В цей файл записуються всі вихідні дані процесу. По замовчуванню дані виводяться на екран терміналу (пристрій/dev/tty), але їх також можна імпортувати в файл або послати ппо каналу іншого процесу.

Файл стандартного потоку помилок (siderr) має дескриптор 2. В цей файл записуються повідомлення про помилки, що виникають під час виконання команди. За промовчанням повідомлення про помилки виводяться на екран терміналу (пристрій /dev/tty), але їх також можна імпортувати в файл. Навіщо ж для реєстрації помилок виділяти спеціальний файл? Справа в тому, що це дуже зручний спосіб виділення з результатів роботи команди власне вихідних даних, а також гарна можливість ефективно організувати ведення різного роду журнальних файлів.

Утиліти використовують тільки стандартні потоки. Для таких програм оболонка дозволяє незалежно перенаправляти ппотоки введення/виводу. Наприклад, можна придушити вивід повідомлень psp помилки, встановити введення або виведення з файлу.

пТ.е. при натисненні команд можна вказувати, звідки слід приймати вхідні дані і куди необхідно направляти вихідні дані, па також повідомлення про помилки. За замовчуванням, якщо не вказано інше, мається на увазі робота з терміналом: дані вводяться з клавіатури пі виводяться на екран. Але інтерпретатор shell має механізмом переадресації, що дозволяє асоціювати стандартні потоки пс різними файлами. При цьому під час перенаправлення стандартного потоку помилок слід вказувати дескриптор файлу (2). Для потоків вводу та виводу робити це не обов'язково.

Окремий випадок використання механізму перенаправлення потоків - перенаправлення в /dev/null, що дозволяє позбутися непотрібних повідомлень на екран. За допомогою того ж механізму можна створювати порожні файли:

% cat < /dev/null > myfile - створить в поточній директорії порожній файл myfile.

/dev/null - спеціальний файл, який представляє собою т. н. «порожній пристрій». Запис у нього відбувається успішно, незалежно від обсягу «записаної інформації. Читання з /dev/null еквівалентно зчитування кінця файлу EOF.

Перенаправлення потоків введення-виведення здійснюється, подібно DOS (Точніше, синтаксис перенаправлення потоків ОС DOS сприйняла піт UNIX) за допомогою символів:


> - перенаправлення стандартного потоку виводу >> - перенаправлення стандартного потоку виводу у режимі записування < - перенаправлення стандартного потоку вводу << - отримання дані зі стандартного потоку вводу до тих пір, поки не зустрінеться розділювач Однак, на відміну від DOS при створенні програмного каналу між двома процесами пОС UNIX/Linux запускає обидва процесу одночасно і здійснює передачу інформації через системний буфер (без проміжної запису на диск). Таким чином, програмні канали в ОС UNIX/Linux є дуже ефективним способом обміну. У разі ппереполнения системного буфера (наприклад, якщо `передавальна"" програма видає інформацію в канал швидше, ніж її може обробити `приймаюча"" програма) ОС автоматично припиняє той процес, який здійснює запис у канал до звільнення буфера.


Найпоширеніші оператори переадресації

№п/п Синтаксис Опис 1 команда > файл Направляє стандартний потік виводу в новий файл

2 команда 1> файл Направляє стандартний потік виводу у вказаний файл

3 команда >> файл Направляє стандартний потік виводу у вказаний файл (режим приєднання)

4 команда > файл 2>&1 Направляє стандартні потоки виводу і помилок у вказаний файл

5 команда 2> файл Направляє стандартний потік помилок у вказаний файл

6 команда 2>> файл Направляє стандартний потік помилок у вказаний файл (режим приєднання)

7 команда >> файл 2>&1 Направляє стандартні потоки виводу і помилок у вказаний файл (режим приєднання)

8 команда < файл1 > файл2 Отримує вхідні дані з першого файлу і направляє вихідні дані у другий файл

9 команда < файл в якості стандартного вхідного потоку отримує дані з вказаного файлу

10 команда << розділювач Отримує дані зі стандартного потоку вводу до тих пір, поки не зустрінеться розділювач

11 команда <&m В якості стандартного вхідного потоку отримує дані з файлу з дескриптором m

12 команда >&m Направляє стандартний потік виводу в файл з дескриптором m пОператор n>&m дозволяє перенаправляти файл з дескриптором n туди, куди спрямований файл з дескриптором m. пПодобных операторів в командному рядку може бути декілька, в цьому випадку вони обчислюються зліва направо.


Команда exec і застосування дескрипторів файлів

команда exec замінює поточний інтерпретатор shell зазначеної командою. Вона зазвичай використовується для того, щоб закрити інтерпретатор і запустити інший. Але в неї є й інше застосування.

Наприклад, команда виду


exec < файл робить вказаний файл стандартним вхідним потоком всіх команд. Виконувати її в інтерактивному режимі немає сенсу - вона призначена для використання в сценаріях, щоб всі йдуть після неї команди читали свої вхідні дані з файлу. У цьому випадку наприкінці сценарію обов'язково повинна стояти команда

exec <&- яка закриває стандартний потік вводу (в даному випадку файл). Подібний прийом застосовується переважно в сценаріях, що виконуються при виході з системи.

Команда exec < файл не тільки призначає файл стандартним вхідним потоком всіх команд сценарію, але і перезаписує вказівник миші на файл з дескриптором 0 (stdin). Відновити цей покажчик можна буде тільки після закінчення роботи сценарію. Якщо ж у сценарії передбачається продовжити читання даних з клавіатури, то необхідно зберегти вказівник на колишній вхідний потік. Нижче наведено невеликий сценарій, в якому демонструється, як це зробити.

$ cat f_desc

  1. !/bin/bash

exec 3<&0 0<file read linel read line2 exec 0<&3 echo $1inel echo $line2

Перша команда exec зберігає вказівник на стандартний потік вводу (stdin) в файл з дескриптором 3 (допускається будь-яке ціле число в діапазоні від 3 до 9), а потім відкриває файл file для читання. Наступні дві команди read читають з файлу два рядки тексту. Друга команда exec відновлює вказівник на стандартний потік вводу: тепер він пов'язаний з файлом stdin, а не file. Завершальні команди echo відображають на екрані вміст прочитаних рядків, які були збережені в змінних linel і Iine2.

Результат роботи сценарію: /$. f_desc Привіт! Поки