- Linux: перенаправление
- Три стандартных потока ввода/вывода
- Перенаправление стандартного потока вывода
- Перенаправление стандартного потока ввода
- Перенаправление стандартного потока ошибок
- Итоги
- Фундаментальные основы Linux. Часть IV. Программные каналы и команды
- Глава 16. Перенаправление потоков ввода/вывода
- Потоки данных stdin, stdout и stderr
- Перенаправление стандартного потока вывода
- Перенаправление стандартного потока ошибок
- Перенаправление стандартного потока вывода и программные каналы
- Объединение стандартных потоков вывода stdout и ошибок stderr
- Перенаправление стандартного потока ввода
- Неоднозначное перенаправление потоков ввода/вывода
- Быстрая очистка содержимого файла
- Практическое задание: перенаправление потоков ввода/вывода
- Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода
Linux: перенаправление
Если вы уже освоились с основами терминала, возможно, вы уже готовы к тому, чтобы комбинировать изученные команды. Иногда выполнения команд оболочки по одной вполне достаточно для решения некоей задачи, но в некоторых случаях вводить команду за командой слишком утомительно и нерационально. В подобной ситуации нам пригодятся некоторые особые символы, вроде угловых скобок.
Для оболочки, интерпретатора команд Linux, эти дополнительные символы — не пустая трата места на экране. Они — мощные команды, которые могут связывать воедино различные фрагменты информации, разделять то, что было до этого цельным, и делать ещё много всего. Одна из самых простых, и, в то же время, мощных и широко используемых возможностей оболочки — это перенаправление стандартных потоков ввода/вывода.
Три стандартных потока ввода/вывода
Для того, чтобы понять то, о чём мы будем тут говорить, важно знать, откуда берутся данные, которые можно перенаправлять, и куда они идут. В Linux существует три стандартных потока ввода/вывода данных.
Первый — это стандартный поток ввода (standard input). В системе это — поток №0 (так как в компьютерах счёт обычно начинается с нуля). Номера потоков ещё называют дескрипторами. Этот поток представляет собой некую информацию, передаваемую в терминал, в частности — инструкции, переданные в оболочку для выполнения. Обычно данные в этот поток попадают в ходе ввода их пользователем с клавиатуры.
Второй поток — это стандартный поток вывода (standard output), ему присвоен номер 1. Это поток данных, которые оболочка выводит после выполнения каких-то действий. Обычно эти данные попадают в то же окно терминала, где была введена команда, вызвавшая их появление.
И, наконец, третий поток — это стандартный поток ошибок (standard error), он имеет дескриптор 2. Этот поток похож на стандартный поток вывода, так как обычно то, что в него попадает, оказывается на экране терминала. Однако, он, по своей сути, отличается от стандартного вывода, как результат, этими потоками, при желании, можно управлять раздельно. Это полезно, например, в следующей ситуации. Есть команда, которая обрабатывает большой объём данных, выполняя сложную и подверженную ошибкам операцию. Нужно, чтобы полезные данные, которые генерирует эта команда, не смешивались с сообщениями об ошибках. Реализуется это благодаря раздельному перенаправлению потоков вывода и ошибок.
Как вы, вероятно, уже догадались, перенаправление ввода/вывода означает работу с вышеописанными потоками и перенаправление данных туда, куда нужно программисту. Делается это с использованием символов > и в различных комбинациях, применение которых зависит от того, куда, в итоге, должны попасть перенаправляемые данные.
Перенаправление стандартного потока вывода
Предположим, вы хотите создать файл, в который будут записаны текущие дата и время. Дело упрощает то, что имеется команда, удачно названная date , которая возвращает то, что нам нужно. Обычно команды выводят данные в стандартный поток вывода. Для того, чтобы эти данные оказались в файле, нужно добавить символ > после команды, перед именем целевого файла. До и после > надо поставить пробел.
При использовании перенаправления любой файл, указанный после > будет перезаписан. Если в файле нет ничего ценного и его содержимое можно потерять, в нашей конструкции допустимо использовать уже существующий файл. Обычно же лучше использовать в подобном случае имя файла, которого пока не существует. Этот файл будет создан после выполнения команды. Назовём его date.txt . Расширение файла после точки обычно особой роли не играет, но расширения помогают поддерживать порядок. Итак, вот наша команда:
Нельзя сказать, что сама по себе эта команда невероятно полезна, однако, основываясь на ней, мы уже можем сделать что-то более интересное. Скажем, вы хотите узнать, как меняются маршруты вашего трафика, идущего через интернет к некоей конечной точке, ежедневно записывая соответствующие данные. В решении этой задачи поможет команда traceroute , которая сообщает подробности о маршруте трафика между нашим компьютером и конечной точкой, задаваемой при вызове команды в виде URL. Данные включают в себя сведения обо всех маршрутизаторах, через которые проходит трафик.
Так как файл с датой у нас уже есть, будет вполне оправдано просто присоединить к этому файлу данные, полученные от traceroute . Для того, чтобы это сделать, надо использовать два символа > , поставленные один за другим. В результате новая команда, перенаправляющая вывод в файл, но не перезаписывающая его, а добавляющая новые данные после старых, будет выглядеть так:
Теперь нам осталось лишь изменить имя файла на что-нибудь более осмысленное, используя команду mv , которой, в качестве первого аргумента, передаётся исходное имя файла, а в качестве второго — новое:
Перенаправление стандартного потока ввода
Используя знак вместо > мы можем перенаправить стандартный ввод, заменив его содержимым файла.
Предположим, имеется два файла: list1.txt и list2.txt , каждый из которых содержит неотсортированный список строк. В каждом из списков имеются уникальные для него элементы, но некоторые из элементов список совпадают. Мы можем найти строки, которые имеются и в первом, и во втором списках, применив команду comm , но прежде чем её использовать, списки надо отсортировать.
Существует команда sort , которая возвращает отсортированный список в терминал, не сохраняя отсортированные данные в файл, из которого они были взяты. Можно отправить отсортированную версию каждого списка в новый файл, используя команду > , а затем воспользоваться командой comm . Однако, такой подход потребует как минимум двух команд, хотя то же самое можно сделать в одной строке, не создавая при этом ненужных файлов.
Итак, мы можем воспользоваться командой для перенаправления отсортированной версии каждого файла команде comm . Вот что у нас получилось:
Круглые скобки тут имеют тот же смысл, что и в математике. Оболочка сначала обрабатывает команды в скобках, а затем всё остальное. В нашем примере сначала производится сортировка строк из файлов, а потом то, что получилось, передаётся команде comm , которая затем выводит результат сравнения списков.
Перенаправление стандартного потока ошибок
И, наконец, поговорим о перенаправлении стандартного потока ошибок. Это может понадобиться, например, для создания лог-файлов с ошибками или объединения в одном файле сообщений об ошибках и возвращённых некоей командой данных.
Например, что если надо провести поиск во всей системе сведений о беспроводных интерфейсах, которые доступны пользователям, у которых нет прав суперпользователя? Для того, чтобы это сделать, можно воспользоваться мощной командой find .
Обычно, когда обычный пользователь запускает команду find по всей системе, она выводит в терминал и полезные данные и ошибки. При этом, последних обычно больше, чем первых, что усложняет нахождение в выводе команды того, что нужно. Решить эту проблему довольно просто: достаточно перенаправить стандартный поток ошибок в файл, используя команду 2> (напомним, 2 — это дескриптор стандартного потока ошибок). В результате на экран попадёт только то, что команда отправляет в стандартный вывод:
Как быть, если нужно сохранить результаты работы команды в отдельный файл, не смешивая эти данные со сведениями об ошибках? Так как потоки можно перенаправлять независимо друг от друга, в конец нашей конструкции можно добавить команду перенаправления стандартного потока вывода в файл:
Обратите внимание на то, что первая угловая скобка идёт с номером — 2> , а вторая без него. Это так из-за того, что стандартный вывод имеет дескриптор 1, и команда > подразумевает перенаправление стандартного вывода, если номер дескриптора не указан.
И, наконец, если нужно, чтобы всё, что выведет команда, попало в один файл, можно перенаправить оба потока в одно и то же место, воспользовавшись командой &> :
Итоги
Тут мы разобрали лишь основы механизма перенаправления потоков в интерпретаторе командной строки Linux, однако даже то немногое, что вы сегодня узнали, даёт вам практически неограниченные возможности. И, кстати, как и всё остальное, что касается работы в терминале, освоение перенаправления потоков требует практики. Поэтому рекомендуем вам приступить к собственным экспериментам с > и .
Уважаемые читатели! Знаете ли вы интересные примеры использования перенаправления потоков в Linux, которые помогут новичкам лучше освоиться с этим приёмом работы в терминале?
Источник
Фундаментальные основы Linux. Часть IV. Программные каналы и команды
Оригинал: Linux Fundamentals
Автор: Paul Cobbaut
Дата публикации: 16 октября 2014 г.
Перевод: А.Панин
Дата перевода: 15 декабря 2014 г.
Глава 16. Перенаправление потоков ввода/вывода
Одной из мощных возможностей командной оболочки системы Unix является механизм перенаправления потоков ввода/вывода с возможностью задействования программных каналов .
В данной главе даются пояснения относительно перенаправления стандартных потоков ввода, вывода и ошибок.
Потоки данных stdin, stdout и stderr
Командная оболочка bash поддерживает три типа базовых потоков данных; она принимает данные из стандартного потока ввода stdin (поток 0 ), отправляет данные в стандартный поток вывода stdout (поток 1 ), а также отправляет сообщения об ошибках в стандартный поток ошибок stderr (поток 2 ).
Приведенная ниже иллюстрация является графической интерпретацией этих трех потоков данных.
Клавиатура обычно служит источником данных для стандартного потока ввода stdin , в то время, как стандартные потоки вывода stdout и ошибок stderr используются для вывода данных. Новых пользователей Linux может смущать подобное разделение, так как не существует очевидного способа дифференцирования стандартных потоков вывода stdout и ошибок stderr . Опытные же пользователи знают о том, что разделение стандартных потоков вывода и ошибок может оказаться весьма полезным.
В следующем разделе будет рассказано о том, как осуществляется перенаправление упомянутых потоков данных.
Перенаправление стандартного потока вывода
Операция перенаправления потока данных stdout (>)
Перенаправление стандартного потока вывода stdout может быть осуществлено с помощью символа знака «больше» . В том случае, если при разборе строки команды командная оболочка обнаруживает символ знака >, она удаляет данные из файла и перенаправлет данные из стандартного потока вывода в него.
командная оболочка будет рассматривать только два аргумента (echo = аргумент 0, привет = аргумент 1). Описание операции перенаправления потока данных удаляется перед началом подсчета количества аргументов.
Содержимое выходного файла удаляется
Параметр командной оболочки noclobber
Нейтрализация влияния параметра командной оболочки noclobber
Перенаправление стандартного потока ошибок
Операция перенаправления потока данных stderr (2>)
Перенаправление стандартного потока ошибок осуществляется с помощью оператора 2> . Такое перенаправление может оказаться очень полезным для предотвращения заполнения вашего экрана сообщениями об ошибках.
Операция перенаправления нескольких потоков данных 2>&1
позволяет перенаправить только данные из стандартного потока вывода в файл dirlist, так как с помощью данной команды осуществляется копирование дескриптора стандартного потока вывода в дескриптор стандартного потока ошибок перед тем, как стандартный поток вывода перенаправляется в файл dirlist.
Перенаправление стандартного потока вывода и программные каналы
Объединение стандартных потоков вывода stdout и ошибок stderr
Перенаправление стандартного потока ввода
Операция перенаправления потока данных stdin ( стандартного потока ввода stdin осуществляется с помощью оператора here document (иногда называемая структурой here-is-document) является механизмом для ввода данных до момента обнаружения определенной последовательности символов (обычно EOF). Маркер EOF может быть либо введен вручную, либо вставлен автоматически при нажатии комбинации клавиш Ctrl-D.
Структура here string может использоваться для непосредственной передачи строк команде. При использовании данной структуры достигается такой же эффект, как и при использовании команды echo строка | команда (но вы сможете избежать создания одного дополнительного процесса).
Для получения дополнительной информации об алгоритме base64 следует обратиться к стандарту rfc 3548.
Неоднозначное перенаправление потоков ввода/вывода
Быстрая очистка содержимого файла
Практическое задание: перенаправление потоков ввода/вывода
1. Активируйте параметр командной оболочки noclobber .
2. Проверьте, активирован ли параметр noclobber , повторив вызов команды вывода содержимого директории ls для директории /etc с перенаправлением данных из стандартного потока вывода в файл.
3. Какой из символов представляет параметр noclobber в списке всех параметров командной оболочки.
4. Деактивируйте параметр noclobber .
5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл tailing.txt . После этого выполните команду tail -f tailing.txt . Используйте вторую командную оболочку для добавления строки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке.
6. Создайте файл, содержащий имена пяти людей. Используйте команду cat и механизм перенаправления потоков ввода/вывода для создания файла, а также структуру here document для завершения ввода.
Корректная процедура выполнения практического задания: перенаправление потоков ввода/вывода
1. Активируйте параметр командной оболочки noclobber .
2. Проверьте, активирован ли параметр noclobber , повторив вызов команды вывода содержимого директории ls для директории /etc с перенаправлением данных из стандартного потока вывода в файл.
3. Какой из символов представляет параметр noclobber в списке всех параметров командной оболочки.
4. Деактивируйте параметр noclobber .
5. Убедитесь в том, что вы имеете доступ к двум командным оболочкам, открытым на одном компьютере. Создайте пустой файл tailing.txt . После этого выполните команду tail -f tailing.txt . Используйте вторую командную оболочку для добавления строки текста в этот файл. Убедитесь в том, что эта строка была выведена в первой командной оболочке.
6. Создайте файл, содержащий имена пяти людей. Используйте команду cat и механизм перенаправления потоков ввода/вывода для создания файла, а также структуру here document для завершения ввода.
Источник