Поиск по сайту:

Как передавать и перенаправлять как профессионал в командной строке Linux


Ключевые выводы

  • Команды Linux могут использовать стандартные потоки для ввода, вывода и сообщений об ошибках.
  • Перенаправление отправляет выходной поток в файл вместо окна терминала.
  • Конвейер позволяет объединять команды, так что выходные данные одной становятся входными данными для другой.

В Linux каналы и перенаправление позволяют эффективно использовать выходные данные команд. Запишите его в файлы или используйте в качестве входных данных для других команд. Вот что вам нужно знать.

Что такое потоки?

В Linux, как и в других Unix-подобных операционных системах, существует концепция потоков. Каждый процесс имеет входной поток, называемый stdin, выходной поток, называемый stdout, и поток ошибок, называемый stderr. Потоки Linux, как и потоки в реальном мире, имеют две конечные точки. У них есть источник, или вход, и пункт назначения, или выход.

Входной поток может поступать с клавиатуры на команду, что позволяет отправлять текст, например информацию или команды, в процесс. Выходной поток поступает от команды, обычно в окно терминала. Поток stderr также записывает данные в окно терминала.

Вы можете перенаправлять потоки и передавать их по каналам. Перенаправление означает отправку вывода куда-либо, кроме окна терминала. Конвейер означает получение выходных данных одной команды и использование их в качестве входных данных для другой команды.

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

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

Самая простая форма перенаправления принимает выходные данные команды и отправляет их в файл. Даже этот тривиальный случай может оказаться полезным. Возможно, вам требуется запись вывода команды, или, может быть, вывод прокручивается так сильно, что вы не можете его прочитать.

На этом тестовом компьютере команда du выводит 1380 строк текста. Мы отправим это в файл.

        du > disk-usage.txt
    

Правая угловая скобка указывает оболочке перенаправить вывод stdout команды du в файл с именем disk-usage.txt. Никакие выходные данные не отправляются в окно терминала.

Мы можем использовать ls для проверки создания файла и wc для подсчета строк, слов и букв в файле. Как и ожидалось, wc сообщает, что в файле 1380 строк.

        ls 
wc disk-usage.txt
    

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

        ls /home/dave-mckay/ -R >> disk-usage.txt 
wc disk-usage.txt 
    

Используя опцию -N (номера строк) с less, мы можем убедиться, что новая информация была добавлена после строки 1380.

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

        wc disk-usage.txt missing-file.txt > results.txt 
wc: missing-file.txt: No such file or directory
cat results.txt
    

Результаты для disk-usage.txt отправляются в файл results.txt, но сообщение об ошибке для несуществующего файла Missing-file.txt отправляется в окно терминала.

Мы можем добавить числовые индикаторы в правую угловую скобку, чтобы было понятно, какой поток мы перенаправляем. Поток 1 — это стандартный вывод, а поток 2 — стандартный вывод. Мы можем довольно легко перенаправить стандартный вывод в один файл, а стандартный вывод — в другой.

        wc disk-usage.txt missing-file.txt 1> results.txt 2> error.txt 
cat results.txt
cat error.txt
    

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

        wc disk-usage.txt missing-file.txt 1> results.txt 2>&1
cat results.txt
    

Любые сообщения об ошибках фиксируются и отправляются в тот же файл, что и стандартный вывод.

Возможно, вы вообще не захотите сохранять какие-либо выходные данные, вам просто не нужно, чтобы что-либо записывалось в окно терминала. Файл нулевого устройства, который молча поглощает все отправленное на него сообщение, является удобным местом назначения для отправки нежелательного вывода на экран.

        rm disk-usage.txt missing-file.txt 1> /dev/null 2>&1
    

Ни сообщения stdout, ни stderr не записываются в окно терминала, даже если один из файлов, которые мы удаляем, не существует.

И последний трюк, который вы можете сделать с перенаправлением, — это прочитать файл в поток stdin команды.

        wc < /etc/passwd
    

Вы можете объединить это с перенаправлением вывода.

        wc < /etc/passwd > results.txt
cat results.txt
    

Проведение потоков через трубы

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

Чтобы передать вывод одной команды в другую, мы используем канал «| символ. Например, если бы мы хотели рекурсивно перечислить все файлы и подкаталоги в вашем домашнем каталоге, вы бы увидели быстрое размытие по мере того, как выходные данные ls проносились бы в окне терминала.

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

        ls -R ~ | less
    

Это более эффективно, чем двухэтапный ручной процесс отправки вывода в файл и открытия файла в меньшем объеме.

Передача вывода через другую команду

Конвейер действительно вступает в свои права, когда вторая команда выполняет дальнейшую обработку выходных данных первой команды.

Давайте посчитаем количество учетных записей пользователей и псевдопользователей на вашем компьютере. Мы воспользуемся cat для дампа содержимого файла /etc/passwd и передадим его в wc. Опция -l (строки) подсчитает количество строк в этом файле. Поскольку на каждую учетную запись приходится одна строка, она считает учетные записи за нас.

        cat /etc/passwd | wc -l
    

Это звучит много. Давайте посмотрим названия этих аккаунтов. На этот раз мы передадим cat в awk. Команде awk предлагается использовать двоеточие «:» в качестве разделителя полей и печатать первое поле.

        cat /etc/passwd | awk -F: '{print $1}'
    

Мы можем продолжать добавлять команды. Чтобы отсортировать список, добавьте команду сортировки, чтобы выходные данные awk передавались команде сортировки.

        cat /etc/passwd | awk -F: '{print $1}' | sort
    

Передача вывода через цепочку команд

Вот набор из четырех команд, объединенных тремя каналами. команда ps выводит список запущенных процессов. Опция -e (все) перечисляет все процессы, а опция -o (вывод) указывает, какую информацию следует сообщать. Токен связи означает, что мы хотим видеть только имя процесса.

Список имен процессов затем передается в grep, который отфильтровывает процессы, в имени которых есть chrome. Этот отфильтрованный список передается в сортировку для сортировки списка. Отсортированный список затем передается в uniq. Опция -c (count) подсчитывает уникальные имена процессов. Затем, просто ради интереса, мы делаем то же самое для Firefox.

        ps -e -o comm | grep chrome | sort | uniq -c
ps -e -o comm | grep firefox | sort | uniq -c
    

Бесконечные комбинации

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

Статьи по данной тематике: