Перенаправление потоков данных

LinuxBeginner
Практиковаться сейчас

Введение

В Linux перенаправление — это мощная функция, позволяющая управлять тем, куда направляются входные и выходные данные команд. Возможно, в предыдущих лабораторных работах вы уже встречали операторы > или >>. Они используются для перенаправления вывода в файлы. Эта лабораторная работа познакомит вас с концепцией перенаправления и проведет через различные практические примеры, подходящие для новичков, не имеющих предварительных знаний о Linux.

Базовое перенаправление вывода

Начнем с основ перенаправления вывода:

  1. Откройте терминал. Вы должны находиться в директории /home/labex/project. Если вы не уверены, введите pwd (print working directory), чтобы проверить свое текущее местоположение.

  2. Создадим новый файл под названием redirect с некоторым содержимым. Введите следующую команду:

    echo 'hello labex' > redirect
    

    Эта команда выполняет два действия:

    • echo 'hello labex' выводит текст "hello labex"
    • Символ > перенаправляет этот вывод в файл с именем redirect

    Если файл не существует, он будет создан. Если он уже существует, его содержимое будет перезаписано.

  3. Теперь добавим больше содержимого в тот же файл:

    echo 'labex.io' >> redirect
    

    Оператор >> похож на >, но вместо перезаписи файла он добавляет новое содержимое в конец уже существующего файла.

  4. Чтобы просмотреть содержимое файла, который мы только что создали и изменили, используйте команду cat:

    cat redirect
    

    Вы должны увидеть обе строки, которые мы добавили в файл: "hello labex" на первой строке и "labex.io" на второй.

Понимание стандартного ввода, вывода и ошибок

Прежде чем мы углубимся в перенаправление, давайте разберемся с тремя важными концепциями:

  1. Стандартный ввод (stdin): это источник ввода по умолчанию, обычно ваша клавиатура. Это место, откуда система ожидает поступления данных.
  2. Стандартный вывод (stdout): это место назначения вывода по умолчанию, обычно ваш экран. Это место, куда система отправляет обычный вывод.
  3. Стандартная ошибка (stderr): это место, куда отправляются сообщения об ошибках, также обычно ваш экран. Оно отделено от stdout, чтобы при необходимости сообщения об ошибках можно было обрабатывать отдельно.

В Linux они представлены файловыми дескрипторами — это просто числа, обозначающие открытые файлы:

Файловый дескриптор Файл устройства Описание
0 /dev/stdin stdin
1 /dev/stdout stdout
2 /dev/stderr stderr

Давайте посмотрим пример того, как мы можем их использовать:

  1. Сначала создадим новую директорию под названием Documents:

    mkdir Documents
    

    Эта команда создает новую директорию. Если вы получили ошибку о том, что директория уже существует, ничего страшного — значит, вы можете использовать существующую.

  2. Теперь создадим C-файл в этой директории:

    cat > Documents/test.c << EOF
    #include <stdio.h>
    
    int main()
    {
        printf("hello world\n");
        return 0;
    }
    EOF
    

    Эта команда выполняет несколько действий:

    • cat > начинает процесс записи в файл
    • Documents/test.c — это файл, в который мы пишем
    • << EOF говорит оболочке продолжать принимать ввод до тех пор, пока она не увидит "EOF" (End Of File)
    • Строки между ними — это содержимое, которое мы записываем в файл
    • Финальный EOF отмечает конец ввода
  3. Теперь просмотрим содержимое этого файла:

    cat Documents/test.c
    

    Вы должны увидеть C-код, который мы только что создали.

Перенаправление стандартной ошибки

Теперь давайте изучим, как перенаправлять стандартную ошибку:

  1. Попробуйте прочитать два файла, один из которых существует, а другой — нет:

    cat Documents/test.c nonexistent.c
    

    Вы увидите содержимое test.c (который существует) и сообщение об ошибке для nonexistent.c (которого не существует). Содержимое test.c отправляется в stdout, а сообщение об ошибке — в stderr.

  2. Теперь перенаправим стандартный вывод в один файл, а стандартную ошибку — в другой:

    cat Documents/test.c nonexistent.c > output.log 2> error.log
    

    Эта команда выполняет несколько действий:

    • cat Documents/test.c nonexistent.c пытается отобразить содержимое обоих файлов
    • > output.log перенаправляет stdout (файловый дескриптор 1) в файл с именем output.log
    • 2> error.log перенаправляет stderr (файловый дескриптор 2) в файл с именем error.log
  3. Просмотрите содержимое обоих файлов:

    echo "Output log:"
    cat output.log
    echo "Error log:"
    cat error.log
    

    Вы должны увидеть содержимое test.c в output.log и сообщение об ошибке для nonexistent.c в error.log.

Объединение стандартного вывода и стандартной ошибки

Иногда может потребоваться перенаправить и стандартный вывод, и стандартную ошибку в один и тот же файл. Это особенно полезно, когда вы хотите захватить весь вывод команды, будь то обычный вывод или сообщения об ошибках.

  1. Давайте попробуем вывести содержимое текущей директории и несуществующей директории одной командой:

    ls -l . nonexistent_directory > combined_output.log 2>&1
    

    Эта команда выполняет несколько действий:

    • ls -l . выводит содержимое текущей директории
    • nonexistent_directory — это попытка вывести содержимое директории, которой не существует
    • > combined_output.log перенаправляет stdout в файл с именем combined_output.log
    • 2>&1 перенаправляет stderr туда же, куда и stdout (в данном случае в combined_output.log)
  2. Теперь проверим содержимое нашего объединенного файла вывода:

    cat combined_output.log
    

    В этом файле вы должны увидеть как список директории, так и сообщение об ошибке для несуществующей директории.

  3. В bash есть сокращенный способ перенаправления stdout и stderr в один и тот же файл:

    ls -l . nonexistent_directory &> another_combined_output.log
    

    Оператор &> эквивалентен > file 2>&1.

  4. Проверьте содержимое этого нового файла:

    cat another_combined_output.log
    

    Вы должны увидеть тот же вывод, что и в предыдущем файле.

Продвинутое использование /dev/null

Устройство /dev/null, часто называемое "битовой корзиной" или "черной дырой", — это специальный файл, который отбрасывает все записанные в него данные. У него есть несколько полезных применений в написании скриптов и операциях в командной строке.

  1. Подавление вывода команды: Мы уже видели, как подавить стандартный вывод:

    ls -l > /dev/null
    

    И как подавить и стандартный вывод, и стандартную ошибку:

    ls -l nonexistent_directory > /dev/null 2>&1
    
  2. Подавление только сообщений об ошибках: Иногда вы хотите видеть вывод, но не хотите видеть сообщения об ошибках:

    ls -l . nonexistent_directory 2> /dev/null
    

    Вы должны увидеть список директории, но не увидеть ошибку о несуществующей директории.

  3. Использование /dev/null как пустого файла: /dev/null можно использовать как пустой входной файл. Это полезно для команд, которым требуется входной файл, но вы не хотите предоставлять никаких реальных данных. Например:

    grep "pattern" /dev/null
    

    Эта команда не выдаст никакого вывода, потому что /dev/null — это пустой файл.

  4. Проверка существования файла: Вы можете использовать /dev/null, чтобы проверить, существует ли файл, не создавая никакого вывода:

    if cp Documents/test.c /dev/null 2> /dev/null; then
      echo "File exists and is readable"
    else
      echo "File does not exist or is not readable"
    fi
    

    Этот скрипт пытается скопировать test.c в /dev/null. Если это удалось, значит, файл существует и доступен для чтения.

  5. Очистка содержимого файла: Вы можете использовать /dev/null для быстрой очистки содержимого файла:

    cat /dev/null > combined_output.log
    

    Проверьте, что файл теперь пуст:

    cat combined_output.log
    

    Вы не должны увидеть никакого вывода, что означает, что файл теперь пуст.

Резюме

В этой лабораторной работе вы узнали о перенаправлении потоков данных в Linux. Вы попрактиковались в:

  1. Базовом перенаправлении вывода с помощью > и >>.
  2. Понимании стандартного ввода, вывода и ошибок.
  3. Перенаправлении стандартной ошибки с помощью 2>.
  4. Отбрасывании вывода путем перенаправления в /dev/null.

Эти методы перенаправления являются мощными инструментами в Linux, позволяющими контролировать, куда направляется вывод ваших команд. Они необходимы для написания скриптов, ведения логов и эффективного управления выводом команд. Продолжая работать с Linux, вы найдете множество ситуаций, где эти методы окажутся полезными.