Цель урока: Получить фундаментальное понимание стандартных потоков ввода/вывода (stdin, stdout, stderr). Освоить операторы перенаправления (>>><) для управления файлами и команду tee для "разветвления" потока. Научиться создавать мощные конвейеры (pipelines) с помощью оператора |, чтобы заставить команды работать в связке, передавая данные от одной к другой.

Я очень рад, что вы продолжаете наше общее обучение :) Мы подошли к теме, которая отделяет простого пользователя командной строки от человека, способного заставить Linux работать на себя. Освоение этого урока - это как научиться читать ноты после того, как вы выучили названия клавиш. Вы сможете составлять из простых команд сложные и мощные "мелодии" для обработки данных.

Часть 1: Теория. Три невидимых потока каждой команды

Каждый раз, когда вы запускаете любую программу или команду в Linux (будь то lscat или сложный скрипт), система автоматически создает для нее три стандартных канала данных, также известных как потоки (streams). Представьте себе рабочего на конвейере - это и есть ваша команда.

  1. Стандартный ввод (stdin, file descriptor 0): Это конвейер, по которому рабочему поступают "сырые материалы". По умолчанию, stdin подключен к вашей клавиатуре. Когда команда ожидает от вас ввода (например, когда вы запускаете apt install и он спрашивает [Y/n]), она читает данные именно из этого потока.

  2. Стандартный вывод (stdout, file descriptor 1): Это основной конвейер, по которому рабочий отправляет готовую "продукцию". По умолчанию, stdout подключен к вашему экрану (терминалу). Результат работы команды ls, список файлов, который вы видите на экране, - это данные, отправленные в stdout.

  3. Стандартный поток ошибок (stderr, file descriptor 2): Это отдельный желоб для брака и служебных сообщений. Если во время работы что-то пошло не так (например, "файл не найден" или "отказано в доступе"), рабочий отправляет сообщение об ошибке именно в этот поток. По умолчанию, stderr тоже подключен к вашему экрану.

Ключевая идея, которую нужно понять: stdout и stderr - это два разных, независимых потока, хотя по умолчанию они оба выводятся на экран. Это сделано для того, чтобы вы могли отделить "хорошие" результаты работы от сообщений об ошибках. Это дает нам невероятную гибкость, как мы сейчас увидим.

Часть 2: Практика. Перенаправление потоков (> >> <)

"Перенаправление" - это процесс "отключения" потока от его стандартного устройства (клавиатуры или экрана) и "подключения" его к файлу.

1. Перенаправление стандартного вывода (stdout)

  • > (Перезаписать): Этот оператор берет всё, что команда отправляет в stdout, и записывает в файл, полностью стирая его предыдущее содержимое. Если файла не существует, он будет создан.

    • Сценарий: Вы хотите сохранить список файлов в вашем домашнем каталоге.

    • Команда:

      # Убедитесь, что вы в домашнем каталоге
      cd
      ls -la > my_files.txt
    • Что произошло: Вы не увидели списка файлов на экране. Почему? Потому что вы перенаправили поток stdout из терминала в файл my_files.txt.

    • Проверка: cat my_files.txt. Вы увидите, что всё содержимое теперь в файле.

    • Опасность: Если вы выполните эту команду еще раз, старый файл my_files.txt будет безвозвратно удален и заменен новым содержимым.

  • >> (Добавить в конец): Этот оператор работает так же, но он не стирает файл, а дописывает новые данные в конец.

    • Сценарий: Вы хотите добавить в ваш файл информацию о текущей дате.

    • Команда:

      date >> my_files.txt
    • Проверка: cat my_files.txt. Вы увидите, что после списка файлов появилась новая строка с датой.

2. Перенаправление стандартного потока ошибок (stderr)

Чтобы перенаправить ошибки, нужно явно указать номер их потока - 2.

  • Сценарий: Вы пытаетесь найти файл в каталоге, где у вас нет прав доступа. Это гарантированно вызовет ошибки.

  • Команда:

    find /etc -name "shadow" 2> error_log.txt
  • Что произошло: На экране вы ничего не увидели, даже ошибок. Все сообщения Permission denied были перенаправлены в файл error_log.txt. Поток stdout (если бы нашлись какие-то файлы) остался бы на экране.

  • Проверка: cat error_log.txt.

3. Перенаправление всего и вся

  • В разные файлы: command > output.txt 2> errors.txt - результат в один файл, ошибки в другой.

  • Всё в один файл (частый прием): command > all_output.txt 2>&1

    • Разбор: > перенаправляет stdout (поток 1) в файл. 2>&1 дословно означает "перенаправить поток 2 (stderr) туда же, куда уже направлен поток 1 (stdout)". Это стандартный способ вести единый лог работы команды.

  • В никуда (/dev/null): В Linux есть специальный файл-пустышка /dev/null. Всё, что в него записывается, исчезает навсегда. Это "черная дыра". Очень полезно, когда вас не интересует вывод команды, а важен лишь сам факт ее выполнения.

    • Сценарий: Вы хотите подавить только сообщения об ошибках.

    • Команда: find /etc -name "shadow" 2> /dev/null

4. Перенаправление стандартного ввода (stdin)

  • < (Взять из файла): Этот оператор отключает stdin от клавиатуры и подключает его к файлу. Команда будет читать данные не от вас, а из файла.

    • Сценарий: У нас есть файл my_files.txt. Мы хотим его отсортировать. Команда sort умеет читать из stdin.

    • Команда:

      sort < my_files.txt
    • Что произошло: Команда sort взяла содержимое файла как входные данные, отсортировала их и вывела результат на экран (в свой stdout).

Часть 3: Практика. Конвейеры (Pipelines |) - Сборочная линия

Это самая мощная и элегантная концепция командной строки. Оператор | (пайп, или "труба") берет stdout команды слева и напрямую "втыкает" его в stdin команды справа. Это позволяет создавать цепочки команд, где результат работы одной становится сырьем для следующей.

  • Сценарий 1: Посчитать количество файлов в текущем каталоге.

    • Команда: ls -1 | wc -l

    • Разбор:

      1. ls -1 выводит список файлов (по одному в строке) в свой stdout.

      2. Оператор | перехватывает этот список.

      3. wc -l (word count, -l = lines) получает этот список на свой stdin и просто считает количество строк, которое ему пришло.

      4. wc выводит итоговое число в свой stdout (на экран).

  • Сценарий 2: Найти 5 самых больших файлов в системе.

    • Команда: find / -type f -exec ls -s {} + 2>/dev/null | sort -n -r | head -n 5

    • Это выглядит страшно, но давайте разберем эту красоту по частям:

      1. find / -type f -exec ls -s {} + 2>/dev/nullfind ищет по всей системе (/) объекты типа "файл" (-type f), для каждой группы найденных файлов выполняет команду ls -s (показать размер в блоках) и выводит результат в stdout. Мы также отбрасываем все ошибки доступа в "черную дыру".

      2. |: Вывод find (список вида размер имя_файла) передается дальше.

      3. sort -n -r: Команда sort получает этот список на свой stdin. Ключ -n говорит сортировать как числа, а -r - в обратном порядке (reverse). Теперь самый большой файл наверху.

      4. |: Отсортированный список передается дальше.

      5. head -n 5: Команда head получает отсортированный список на свой stdin и выводит только первые 5 строк в свой stdout (на экран).

  • Команда tee - разветвитель потока
    Иногда нужно и сохранить результат в файл, и передать его дальше по конвейеру. Для этого есть tee.

    • Сценарий: Сохранить список всех процессов в файл и одновременно посчитать их количество.

    • Команда: ps aux | tee process_list.txt | wc -l

    • Разбор:

      1. ps aux выводит список процессов.

      2. tee process_list.txt получает этот список. Он делает две вещи: сохраняет копию в файл process_list.txt и передает оригинал дальше по конвейеру.

      3. wc -l получает список от tee и считает строки.

    • Результат: На экране вы увидите число, а в файле process_list.txt будет полный список процессов.

Итоги урока и домашнее задание

  • Что мы освоили:

    • Концепцию трех стандартных потоков: stdinstdoutstderr.

    • Перенаправление вывода (>>>) и ошибок (2>).

    • Перенаправление ввода (<).

    • Создание мощных конвейеров команд с помощью |.

    • Использование /dev/null для подавления вывода.

    • Использование tee для сохранения промежуточных результатов.

  • Ваше десятое задание:

    1. Создайте в вашем домашнем каталоге директорию logs.

    2. Выполните команду ls -R /etc (рекурсивный листинг каталога /etc) и перенаправьте и стандартный вывод, и стандартные ошибки в один файл logs/etc_list_full.log.

    3. Используя только конвейер | и команду cat, посчитайте, сколько всего строк в созданном вами файле logs/etc_list_full.log. (Подсказка: cat ... | ...).

    4. Теперь создайте более "чистый" список: выполните ту же команду ls -R /etc, но на этот раз перенаправьте только ошибки в /dev/null, а "хороший" вывод (stdout) - в файл logs/etc_list_clean.log.

    5. Напишите одну единственную команду, которая:

      • Выведет содержимое файла /var/log/auth.log.

      • Отфильтрует его, оставив только строки, содержащие слово session (используйте grep).

      • Сохранит этот отфильтрованный результат в файл logs/session_activity.log.

      • И одновременно с сохранением выведет на экран количество таких строк (используйте tee и wc -l).

На следующем уроке мы начнем применять все наши знания для написания простых скриптов на bash. Мы перейдем от однострочных команд к созданию многоразовых программ для автоматизации наших задач.

Перейти к просмотру - УРОК №12.

подарок Промо-код: PROMO15 - скидка 15%! огонь

Введите при оформлении первого заказа на сайте: Hosting-VDS.com

авторское право цифровые решения

Помог ли вам данный ответ? 0 Пользователи нашли это полезным (0 голосов)