Используйте каналы Linux, чтобы определить, как работают утилиты командной строки. Упростите сложные процессы и повысьте свою производительность, используя набор отдельных команд и превращая их в единую команду. Мы покажем вам, как.
Трубы везде
Каналы — это одна из самых полезных функций командной строки, которые есть в Linux и Unix-подобных операционных системах. Трубы используются бесчисленными способами. Посмотрите на любую статью о командной строке Linux — на любом веб-сайте, не только на нашем, — и вы увидите, что каналы появляются чаще, чем нет. Я просмотрел некоторые статьи Linux How-To Geek, и во всех них используются каналы, так или иначе.
Каналы Linux позволяют вам выполнять действия, которые не поддерживаются «из коробки» оболочкой . Но поскольку философия проектирования Linux состоит в том, чтобы иметь много небольших утилит, которые очень хорошо выполняют свои выделенные функции , и без лишней функциональности — мантры «делай одно и делай хорошо» — вы можете соединять строки команд вместе с каналами, чтобы вывод одной команды становится вводом другой. Каждая команда, в которую вы играете, приносит свой уникальный талант в команду, и вскоре вы обнаружите, что собрали команду-победителя.
Простой пример
Предположим, у нас есть каталог, полный файлов разных типов. Мы хотим знать, сколько файлов определенного типа находится в этом каталоге. Есть и другие способы сделать это, но цель этого упражнения — представить каналы, поэтому мы собираемся сделать это с помощью каналов.
Мы можем легко получить список файлов, используя ls
:
Ls
Чтобы выделить интересующий тип файла, мы будем использовать grep
. Мы хотим найти файлы со словом «page» в имени файла или расширении файла.
Мы будем использовать специальный символ оболочки « |
», Чтобы передать вывод из ls
в grep
.
ls | grep "страница"
grep
печатает строки, соответствующие шаблону поиска . Таким образом, это дает нам список, содержащий только файлы «.page».
Даже этот тривиальный пример отображает функциональность каналов. Вывод ls
не был отправлен в окно терминала. Он был отправлен в grep
как данные для работы с командой grep
. Вывод, который мы видим, происходит от grep,
который является последней командой в этой цепочке.
Расширение нашей цепочки
Давайте начнем расширять нашу цепочку команд. Мы можем посчитать файлы «.page» , добавив команду wc
. Мы будем использовать опцию -l
(количество строк) с wc
. Обратите внимание, что мы также добавили опцию -l
(длинный формат) в ls
. Мы будем использовать это в ближайшее время.
ls - | grep "страница" | туалет
grep
больше не последняя команда в цепочке, поэтому мы не видим ее вывод. Выходные данные grep
передаются в команду wc
. Вывод, который мы видим в окне терминала, сделан из wc
. wc
сообщает, что в каталоге 69 «.page» файлов.
Давайте расширим вещи снова. Мы возьмем команду wc
из командной строки и заменим ее на awk
. В выводе ls
есть девять столбцов с опцией -l
(длинный формат). Мы будем использовать awk
для печати столбцов пять, три и девять. Это размер, владелец и имя файла.
ls -l | grep "страница" | awk '{print $ 5 "" $ 3 "" $ 9}'
Мы получаем список этих столбцов для каждого соответствующего файла.
Теперь мы передадим этот вывод через команду sort
. Мы будем использовать опцию -n
(числовой), чтобы sort
знала, что первый столбец следует рассматривать как числа .
ls -l | grep "страница" | awk '{print $ 5 "" $ 3 "" $ 9}' | сортировать -n
Вывод теперь сортируется в порядке размера файла, с нашим индивидуальным выбором из трех столбцов.
Добавление другой команды
Мы закончим добавлением команды tail
. Мы скажем это перечислить только последние пять строк вывода .
ls -l | grep "страница" | awk '{print $ 5 "" $ 3 "" $ 9}' | сортировать -n | хвост -5
Это означает, что наша команда переводит что-то вроде «покажите мне пять самых больших« .page »файлов в этом каталоге, упорядоченные по размеру». Конечно, нет команды для этого, но с помощью каналов мы создали свой собственный , Мы могли бы добавить это — или любую другую длинную команду — как псевдоним или функцию оболочки, чтобы сохранить всю типизацию.
Вот вывод:
Мы могли бы изменить порядок размеров, добавив опцию -r
(reverse) к команде sort
и используя head
вместо tail
чтобы выбрать строки в верхней части вывода .
На этот раз пять самых больших «.page» файлов перечислены от самого большого до самого маленького:
Некоторые недавние примеры
Вот два интересных примера из недавних статей о гике.
Некоторые команды, такие как команда xargs
, предназначены для ввода данных по ним . Вот способ, которым мы можем заставить wc
считать слова, символы и строки в нескольких файлах, xargs
ls
в xargs
который затем xargs
список имен файлов в wc
как если бы они были переданы в wc
качестве параметров командной строки.
ls * .page | xargs wc
Общее количество слов, символов и строк указано в нижней части окна терминала.
Вот способ получить отсортированный список уникальных расширений файлов в текущем каталоге со счетчиком каждого типа.
ls | рев | cut -d '.' -f1 | рев | сортировать | uniq -c
Здесь много чего происходит.
- ls : список файлов в каталоге
- rev : переворачивает текст в именах файлов.
- cut : вырезает строку при первом появлении указанного разделителя «.». Текст после этого отбрасывается.
- rev : инвертирует оставшийся текст , который является расширением имени файла.
- sort : сортировка списка по алфавиту.
- uniq : подсчитывает количество каждой уникальной записи в списке .
Выходные данные показывают список расширений файлов, отсортированных в алфавитном порядке с количеством каждого уникального типа.
Именованные трубы
Нам доступен еще один тип трубы, называемый именованными трубами. Каналы в предыдущих примерах создаются на лету оболочкой, когда она обрабатывает командную строку. Трубы создаются, используются, а затем отбрасываются. Они преходящи и не оставляют следов. Они существуют только до тех пор, пока работает команда, использующая их.
Именованные каналы отображаются в файловой системе как постоянные объекты, поэтому вы можете увидеть их с помощью ls
. Они постоянны, потому что переживут перезагрузку компьютера, хотя любые непрочитанные данные в них в то время будут отброшены.
Именованные каналы использовались много раз, чтобы позволить различным процессам отправлять и получать данные, но я давно не видел, чтобы они использовали этот способ. Без сомнения, есть люди, которые до сих пор используют их с большим эффектом, но я не сталкивался с ними в последнее время. Но для полноты или просто для удовлетворения вашего любопытства, вот как вы можете их использовать.
Именованные каналы создаются с помощью команды mkfifo
. Эта команда создаст именованный канал с именем «geek-pipe» в текущем каталоге.
mkfifo geek-pipe
Мы можем увидеть детали именованного канала, если мы используем команду ls
с опцией -l
(long format):
ls -l geek-pipe
Первым символом в списке является «р», что означает, что это труба. Если бы это было «d», это означало бы, что объект файловой системы является каталогом, а тире «-» означало бы, что это обычный файл.
Использование именованного канала
Давайте использовать нашу трубу. Неназванные каналы, которые мы использовали в наших предыдущих примерах, немедленно передавали данные из команды отправки в команду получения. Данные, отправленные через именованный канал, будут оставаться в канале, пока не будут прочитаны. Данные на самом деле хранятся в памяти, поэтому размер именованного канала не будет изменяться в списках ls
независимо от того, есть ли в нем данные или нет.
Мы собираемся использовать два окна терминала для этого примера. Я буду использовать ярлык:
# Терминал 1
в одном окне терминала и
# Терминал 2
в другой, так что вы можете различать их. Хеш «#» сообщает оболочке, что последующее является комментарием, и игнорировать его.
Давайте возьмем весь наш предыдущий пример и перенаправим его в именованный канал. Итак, мы используем как неназванные, так и именованные каналы в одной команде:
ls | рев | cut -d '.' -f1 | рев | сортировать | uniq -c> geek-pipe
Ничего особенного не произойдет. Вы можете заметить, что вы не вернетесь в командную строку, поэтому что-то происходит.
В другом окне терминала выполните эту команду:
кошка
Мы перенаправляем содержимое именованного канала в cat
, чтобы cat
отобразил это содержимое во втором окне терминала. Вот вывод:
И вы увидите, что вы вернулись в командную строку в первом окне терминала.
Итак, что только что произошло.
- Мы перенаправили некоторый вывод в именованный канал.
- Первое окно терминала не вернулось в командную строку.
- Данные оставались в канале, пока они не были прочитаны из канала во втором терминале.
- Мы вернулись в командную строку в первом окне терминала.
Вы можете подумать, что вы можете запустить команду в первом окне терминала в качестве фоновой задачи, добавив &
в конец команды. И ты был бы прав. В этом случае мы были бы немедленно возвращены в командную строку.
Смысл отказа от фоновой обработки заключался в том, чтобы подчеркнуть, что именованный канал является процессом блокировки . Помещение чего-либо в именованную трубу открывает только один конец трубы. Другой конец не открывается, пока программа чтения не извлечет данные. Ядро приостанавливает процесс в первом окне терминала, пока данные не будут считаны с другого конца канала.
Сила труб
В настоящее время именованные каналы являются чем-то вроде новизны.
Простые старые каналы Linux, с другой стороны, являются одним из наиболее полезных инструментов, которые вы можете иметь в своем наборе оконных инструментов. Командная строка Linux начинает оживать для вас, и вы получаете новое питание, когда вы можете организовать набор команд для создания единой производительности.
Подсказка на разделение: лучше всего писать свои переданные по конвейеру команды, добавляя по одной команде за раз и заставляя эту часть работать, а затем добавляя следующую команду