Как использовать каналы в Linux

Используйте конвейеры Linux, чтобы настроить взаимодействие утилит командной строки. Упростите сложные процессы и повысьте производительность, используя набор отдельных команд и превратив их в единую команду. Мы покажем вам, как это сделать.

Трубы везде

Каналы — одна из самых полезных функций командной строки, которые есть в операционных системах Linux и Unix. Трубы используются бесчисленным количеством способов. Посмотрите любую статью о командной строке Linux — на любом веб-сайте, не только на нашем, — и вы увидите, что конвейеры появляются чаще, чем нет. Я просмотрел некоторые статьи toadmin.ru по Linux, и во всех них так или иначе используются каналы.

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

Простой пример

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

Мы можем легко получить список файлов с помощью ls:

ls

Сбор файлов в каталоге в окне терминала

Чтобы выделить интересующий тип файла, мы будем использовать grep. Мы хотим найти файлы, в имени или расширении которых есть слово «страница».

Мы будем использовать специальный символ оболочки «|» передать вывод ls в grep.

ls | grep "page"

ls -l |  grep

grep печатает строки, которые соответствовать его шаблону поиска. Это дает нам список, содержащий только файлы «.page».

список файлов подкачки в окне терминала

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

Расширение нашей сети

Давайте начнем расширять нашу цепочку конвейерных команд. Мы можем посчитайте файлы «.page» добавив команду wc. Мы будем использовать параметр -l (количество строк) с wc. Обратите внимание, что мы также добавили параметр -l (длинный формат) в ls. Мы скоро воспользуемся этим.

ls - | grep "page" | wc -l

ls - |  grep

grep больше не последняя команда в цепочке, поэтому мы не видим ее вывода. Вывод команды grep передается в команду wc. В окне терминала мы видим вывод из wc. wc сообщает, что в каталоге 69 файлов «.page».

  Как установить Linux

Давайте продолжим снова. Мы уберем команду wc из командной строки и заменим ее на awk. В выводе ls есть девять столбцов с параметром -l (длинный формат). Мы будем использовать awk для столбцы печати пять, три и девять. Это размер, владелец и имя файла.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}'

ls -l |  grep

Мы получаем список этих столбцов для каждого из совпадающих файлов.

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

Теперь мы передадим этот вывод через команду sort. Мы будем использовать параметр -n (числовой), чтобы сортировка знала, что первый столбец должен быть рассматривать как числа.

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n

ls -l |  grep

Теперь вывод отсортирован по размеру файла с нашим индивидуальным выбором из трех столбцов.

Файлы, отсортированные по размеру в окне терминала

Добавление другой команды

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

ls -l | grep "page" | awk '{print $5 " " $3 " " $9}' | sort -n | tail -5

ls -l |  grep

Это означает, что наша команда переводится как «покажите мне пять самых больших файлов« .page »в этом каталоге, отсортированных по размеру». Конечно, для этого нет команды, но, используя каналы, мы создали свою собственную. Мы могли бы добавить эту — или любую другую длинную команду — в качестве псевдонима или функции оболочки, чтобы сохранить весь ввод.

Вот результат:

Пять самых больших файлов .page, перечисленных в порядке размера в окне терминала

Мы могли бы изменить порядок размеров, добавив параметр -r (обратный) к команде сортировки и используя голову вместо хвоста для выбора строк. из верхней части вывода.

ls -l |  grep 

На этот раз пять самых больших файлов с расширением .page перечислены в порядке убывания размера:

Пять самых больших файлов .page в окне терминала в обратном порядке.

Некоторые недавние примеры

Вот два интересных примера из недавних статей для компьютерных фанатов How-To.

Некоторые команды, такие как xargscommand, разработаны чтобы вводить их по трубопроводу. Вот способ, которым мы можем подсчитать слова, символы и строки в нескольких файлах, передав ls в xargs, который затем передает список имен файлов в wc, как если бы они были переданы в wc в качестве параметров командной строки.

ls *.page | xargs wc

ls * .page |  xargs wc в окне терминала

Общее количество слов, символов и строк указано в нижней части окна терминала.

  Как установить Emby Media Server в Linux

Подсчет слов, символов и строк в окне терминала

Вот способ получить отсортированный список уникальных расширений файлов в текущем каталоге со счетчиком каждого типа.

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c

ls |  rev |  вырезать -d '.'  -f1 |  rev |  сортировать |  uniq -c в окне терминала

Здесь много чего происходит.

ls: перечисляет файлы в каталоге
rev: Переворачивает текст в именах файлов.
порез: Режет веревку при первом появлении указанного разделителя «.». Текст после этого отбрасывается.
rev: переворачивает оставшийся текст, который является расширением имени файла.
sort: сортирует список по алфавиту.
uniq: подсчитывает количество каждого уникальная запись в списке.

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

Список уникальных расширений файлов в окне терминала

Именованные каналы

Нам доступен еще один тип каналов — именованные каналы. Каналы в предыдущих примерах создаются оболочкой «на лету», когда она обрабатывает командную строку. Трубы создаются, используются, а затем выбрасываются. Они преходящи и не оставляют после себя никаких следов. Они существуют только до тех пор, пока выполняется команда, их использующая.

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

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

Именованные каналы создаются с помощью команды mkfifo. Эта команда создаст именованный канал называется «geek-pipe» в текущем каталоге.

mkfifo geek-pipe

mkfifo geek-pipe в окне терминала

Мы можем увидеть детали именованного канала, если воспользуемся командой ls с параметром -l (длинный формат):

ls -l geek-pipe

ls -l geek-pipe в окне терминала

Первый символ в списке — это «p», что означает вертикальную черту. Если бы это было «d», это означало бы, что объект файловой системы является каталогом, а тире «-» означало бы, что это обычный файл.

Использование именованного канала

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

  Как сделать резервную копию фотографий с мобильного устройства в Linux с помощью Daemon Sync

В этом примере мы будем использовать два окна терминала. Я использую метку:

# Terminal-1

в одном окне терминала и

# Terminal-2

в другом, так что вы можете различать их. Хэш «#» сообщает оболочке, что далее следует комментарий, и игнорировать его.

Давайте возьмем весь наш предыдущий пример и перенаправим его в именованный канал. Итак, мы используем как безымянные, так и именованные каналы в одной команде:

ls | rev | cut -d'.' -f1 | rev | sort | uniq -c > geek-pipe

ls |  rev |  вырезать -d '.'  -f1 |  rev |  сортировать |  uniq -c> geek-pipe в окне терминала ”width =” 646 ″ height = ”97 ″ onload =” pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this); »  onerror = ”this.onerror = null; pagespeed.lazyLoadImages.loadIfVisibleAndMaybeBeacon (this);”> </p>
<p> Ничего особенного не произойдет.  Вы можете заметить, что не возвращаетесь в командную строку, поэтому что-то происходит. </p>
<p> В другом окне терминала введите следующую команду: </p>
<pre> cat <geek- труба </pre>
<p> <img loading =

Мы перенаправляем содержимое именованного канала в cat, чтобы cat отображал это содержимое во втором окне терминала. Вот результат:

Содержимое названного канала отображается в окне терминала

И вы увидите, что вы вернулись в командную строку в первом окне терминала.

Завершенная задача и командная строка в окне терминала

Итак, что только что произошло.

Мы перенаправили некоторый вывод в именованный канал.
Первое окно терминала не вернулось в командную строку.
Данные оставались в конвейере до тех пор, пока не были прочитаны из канала на втором терминале.
Нас вернули в командную строку в первом окне терминала.

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

Смысл отказа от фоновой обработки заключался в том, чтобы подчеркнуть, что именованный канал является блокирующим процессом. Помещение чего-либо в именованный канал открывает только один конец канала. Другой конец не открывается, пока программа чтения не извлечет данные. Ядро приостанавливает процесс в первом окне терминала до тех пор, пока данные не будут считаны с другого конца канала.

Сила труб

В настоящее время именованные трубы стали чем-то вроде новинки.

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

Заключительный совет: лучше всего писать передаваемые по конвейеру команды, добавляя по одной команде за раз и заставляя эту часть работать, а затем вставляя следующую команду по конвейеру.