Выход из тени: 6 малоизвестных команд Linux

Функциональность Linux не сводится лишь к ls и grep. Уверен, что, скорее всего, вы уже использовали эти инструменты для быстрого поиска и решения простых задач, но это только малая часть возможностей ОС. Большинство дистрибутивов Linux содержат множество встроенных инструментов, которые сразу и не заметишь. Но стоит копнуть глубже, и обнаружится, что Linux включает ряд специальных программ для выполнения самых разных операций: от простых манипуляций с текстом до сложной инженерии сетевого трафика. 

Если вы озадачитесь поиском обучающих программ или руководств по овладению Linux, то непременно найдете превосходные материалы об основах этой ОС. Вне всякого сомнения, вы обязательно должны научиться использовать ключевые команды навигации в командной строке, такие как cd и ls, но Linux предоставляет вам гораздо больше возможностей и без привлечения других сторонних инструментов или языков программирования. 

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

1. tc (Traffic Control)

Это набор инструментов для контроля сетевого трафика внутри Linux. tc предоставляет вам просто головокружительные возможности, от которых захватывает дух. Но ошибочно полагать, что конфигурация управления трафиком является простым процессом. Тем не менее понимание его сути позволит контролировать инженерию трафика прямо в Linux. 

Руководство на этом ресурсе может показаться не совсем удобным, но на Debian Wiki есть более удачно структурированный материал с описанием нескольких способов использования tc.

Чаще всего tc используется для задержки пакетов сетевого подключения. С помощью этой программы вы можете управлять входящими и исходящими пакетами, осуществляя их задержку или даже полное удаление. Рассмотрим относительно простой пример с применением задержки при сетевом подключении. Сначала проверим показатели ping в отношении Google:

pi@raspberry:~ $ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=13.6 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=10.9 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=117 time=15.5 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=117 time=13.8 ms

Не так уж плохо. Между нами и Google ~13.5 мс задержки. А предположим, мы захотели проверить, как будет работать приложение при более длительной задержке. В практику уже давно и прочно вошло стресс-тестирование приложений в условиях слабого Интернет-соединения. Если вы не знаете, как ваше приложение поведет себя в таких неоптимальных сетевых условиях, то вряд ли сможете предсказать, как оно будет функционировать во всех других случаях. 

Вызовем задержку в 100 мс с помощью tc

sudo tc qdisc add dev eth0 root netem delay 100ms

pi@raspberry:~ $ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=117 time=110 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=117 time=116 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=117 time=119 ms
64 bytes from 8.8.8.8: icmp_seq=4 ttl=117 time=113 ms

Превосходно! Теперь мы видим, что имитированная нами задержка в 100ms добавилась к имевшейся ранее. Не забудьте устранить это отклонение после тестирования:

sudo tc qdisc del dev eth0 root

2. whiptail

Классическое окно whiptail с сообщением в терминале

Интересовались ли вы когда-нибудь, как создаются эти милые всплывающие сообщения? Конечно же, с помощью whiptail. Это полезная специализированная утилита для отображения диалоговых окон непосредственно внутри терминала. Возможно, вы обратили внимание, что этот же стиль используется как в процессе установки Ubuntu, так и при других распространенных установках, выполняемых из командной строки.  

Whiptail широко доступен и встроен во многие дистрибутивы для быстрого и простого использования. Эта утилита предоставляет большой выбор различных типов окон и полей для ввода данных: 

  • окна сообщений; 
  • окна ввода произвольного текста; 
  • окна ввода пароля; 
  • окна с выбором “да”/“нет”; 
  • окна меню с множественным выбором; 
  • … и другие варианты!

С помощью whiptail попробуем создать в командной строке простое окно с выбором “yes”/“no”:

whiptail --yesno "would you like to continue?" 10 40

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

Окно с выбором “yes”/“no”, созданное с помощью whiptail 

Чтобы увидеть возвращаемое значение при выборе “yes” или “no”, можно вывести в консоль результат последней выполненной команды. Если вы просто введете echo $?, то увидите либо 0 в случае “yes’’, либо 1 при выборе “no”. Это можно легко включить в сценарий командной строки следующим образом: 

#!/bin/bash

whiptail --yesno "would you like to continue?" 10 40

RESULT=$?

if [ $RESULT = 0 ]; then
  echo "you clicked yes"
else
  echo "you clicked no"
fi

3. shred

Когда вы в последний раз удаляли файл в Linux? Как вы это делали? Удалили с помощью rm и забыли? Если файл содержал какие-либо чувствительные данные, то перед rm в подобных целях, следовало бы хорошо подумать. Как раз для таких ситуаций существует shred. Эта небольшая утилита на самом деле гарантированно стирает файл, многократно записывая поверх него случайные данные.  

Удаляя файл командой rm, вы в действительности просто стираете “ссылку” или его индекс, известный ОС. При этом файл несомненно исчезает, так что вы его больше не видите, но в течение какого-то времени его исходные данные все еще хранятся на жестком диске системы. Эти данные можно восстановить с помощью специальных процедур. Используя shred, вы можете быть уверены, что файл будет удален действительно, что избавит вас от необходимости сжигать компьютер. 

С более подробной информацией о shred вы можете ознакомиться здесь

В следующий раз, когда вы захотите безвозвратно удалить файл, выполните эту команду (флаг -u по-настоящему удаляет текущий файл, а не просто затирает его индекс). 

shred -u <file>

4. split

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

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

echo -e "line1\nline2\nline3\nline4" > test_file

split --lines 2 ./test_file test_file_split_

cat test_file_split_aa && cat test_file_split_ab

В этом случае мы из одного исходного файла создали 2 новых. Команда split позволяет присоединить префикс имени к выходным файлам, что мы и сделали с помощью последнего аргумента команды. Для полной ясности полученные разделенные файлы содержат суффиксы aa и ab.

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

5. nl

Бывало у вас такое  —  смотрите на лог-файл или другой вывод простого текста и думаете: 

“А с нумерацией строк было бы гораздо лучше!” 

Нумерация строк упрощает процессы чтения и запоминания места в тексте или указывает на конкретный раздел. Оставаясь верными исключительно потенциалу Linux, найдем специальную утилиту и для решения этой задачи. С помощью команды nl вы можете буквально нумеровать строки. Принятие какого-либо текста на поток stdin приводит к такому же результату, но с нумерацией строк. Посмотрим: 

echo -e "one\ntwo\nthree"
one
two
three

echo -e "one\ntwo\nthree" | nl
     1 one
     2 two
     3 three

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

echo -e "one\ntwo\nthree" | nl -s ": " -w 1
1: one
2: two
3: three

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

cat <file> | nl

Если вам нравится less для просмотра больших файлов, то можно при открытии файла просто передать аргумент -N для автоматического отображения номеров строк. Это избавит вас от необходимости выполнять дополнительные операции с исходным файлом и добавлять номера строк, поскольку less не загружает файл сразу целиком.

6. flock

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

Используя flock, можно создать разные типы возможных блокировок во время параллельных операций. Сама по себе блокировка в Linux  —  это просто файл. Рассмотрим пример использования блокировки для предотвращения взаимодействия нескольких процессов с файлом: 

LOCKFILE=/tmp/lockfile

already_locked() {
  echo "lock is already held, exiting"
  exit 1
}

exec 200>$LOCKFILE
flock -n 200 || already_locked 
echo "lock obtained, proceeding"
sleep 10
echo "releasing lock, done"

Если запустить этот сценарий командной строки, то он попытается получить блокировку для файла /tmp/lockfile, присвоив ему файловый дескриптор 200 и затем используя “неблокирующий” тип блокировки. При таком виде блокировки, в случае ее получения, все остальные попытки ее получения будут проваливаться вместо того, чтобы ожидать разблокировки.

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

Благодарю за внимание! В недрах Linux скрывается неимоверное число удивительных утилит, готовых к использованию. Представляете, как будет интересно в полной мере овладеть этими оригинальными программами, а также осмыслить конкретное назначение и эффективность каждой из них. В следующий раз, как только вы захотите узнать о других доступных вам возможностях, просто воспользуйтесь ls /usr/bin и начните свое исследование. 

Читайте также:

Читайте нас в Telegram, VK и Яндекс.Дзен


Перевод статьи Tate Galbraith: 6 Lesser-Known Linux Commands You Should Try

Предыдущая статьяЗнакомство с функциональным программированием в Python, JavaScript и Java
Следующая статьяМенеджеры контекста в Python  -  выходим за пределы «with open() file»