Большинство разработчиков, использующих операционные системы на базе и подобные Unix, предпочитают инструктировать компьютер через терминал. Как правило, они оперируют стандартными (POSIX) командами Unix/Linux и другими системными командами для работы с файлами, конфигурации системы и управления процессами. Сэкономить время при работе с командной строкой помогают такие приемы, как комбинирование клавиш терминала, установка псевдонимов и использование комбинаций команд.

Комбинирование нескольких команд Unix/Linux с помощью логического оператора, оператора конкатенации или оператора конвейера  —  отличный способ повысить производительность при работе с терминалом и сценариями оболочки.

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


Техника комбинирования команд

Чаще всего мы вводим одну команду и нажимаем клавишу Return, чтобы выполнить ее, используя Bash в качестве интерпретатора команд терминала. Например, чтобы изменить каталог, мы часто применяем команду mkdir и нажимаем клавишу Return, а затем вводим команду cd. Bash (и другие интерпретаторы командной строки или Z-shell) поддерживает комбинирование команд с помощью различных операторов. Это позволяет объединять несколько команд в одну для повышения производительности.

Вот некоторые приемы комбинирования команд.

  • command1 && command2: сначала выполняет command1, затем command2, если только command1 не вернула ненулевой выходной код.
  • command1 || command2: выполняет command1, затем command2, если только command1 вернула ненулевой выходной код.
  • command1 | command2: последовательно выполняет обе команды, передавая стандартный вывод command1 на стандартный ввод command2.
  • command1 |& command2: работает аналогично оператору |, но передает стандартный вывод и данные об ошибке в command2.
  • command1 ; command2: выполняет последовательно обе команды, независимо от выходного кода (аналогично клавише Return).
  • command1 & command2 &: выполняет обе команды как фоновые задачи.

Теперь посмотрим, как используются эти операторы комбинирования команд с повседневными командами Unix/Linux.


Просмотр истории командной строки и повторное выполнение элементов истории

Программисты, как правило, не часто меняют среду разработки или отказываются от нее. Поэтому им нередко приходится повторно выполнять команды, которые они вводили ранее. Что делать, если нужно снова запустить недавно выполненную команду? Сначала можно нажать клавишу “стрелка вверх” и попытаться найти конкретную команду. Если после введения нужной команды уже прошло какое-то время, воспользуйтесь хорошо известной функцией обратного поиска, нажав Ctrl + R.

Функция обратного поиска работает быстро, но иногда перед выполнением команды необходимо просмотреть все связанные с ней прошлые команды. Есть лучший, встроенный способ обратного поиска, если необходимо искать, сравнивать и выполнять команды из истории командной строки. Можно вести поиск в истории командной строки, комбинируя команды history и grep:

history | grep "npm install"

Приведенная выше команда выдает список всех команд, содержащих npm install, вместе с уникальным номером команды:

Использование команд history и grep с командным конвейером. Скриншот автора

Для мгновенного выполнения нужного элемента истории можно использовать синтаксис !<history_index>. Следуйте этому примеру:

!1575 # Устанавливает TypeScript 

Мгновенный переход в только что созданный каталог

При работе над проектами часто приходится создавать новые каталоги. Например, при выполнении рефакторинга может потребоваться создать несколько каталогов для хранения только что отрефакторенного исходного кода. Обычно используется команда mkdir для создания нового каталога. После этого для перехода в только что созданный каталог применяется команда cd. Можно объединить эти два действия в одно и использовать одну комбинированную команду, как показано ниже:

mkdir app_settings && cd $_

Приведенная выше команда сначала создает каталог app_settings. Затем она изменяет текущий рабочий каталог на app_settings, если только создание каталога было успешным. В Bash параметр $_ расширяется до последнего аргумента предыдущей команды, которым в приведенном примере является app_settings. Вы даже можете поместить эту команду в функцию Bash и определить команду mkdircd.


Выяснение состояния долго выполняющейся команды

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

Не дожидаясь реализации долго выполняющейся команды, программисты обычно переключаются на другие задачи. Как же узнать статус завершения (или отказа) команды?

Большинство дистрибутивов GNU/Linux имеют предустановленные версии zenity и notify-send. Можно использовать их для создания уведомления всякий раз, когда завершается долго выполняемая команда. Посмотрите следующие примеры:

npm install; notify-send Done
apt update; notify-send Done

Можно также выводить уведомление только в случае сбоя конкретной команды следующим образом:

make || notify-send Error

MacOS позволяет создать уведомление с помощью AppleScript. Для этого можно создать псевдоним (например, sleep 5; notif), подобно псевдониму alert в Ubuntu (ср. псевдоним alert в .bashrc).


Выполнение последовательных и параллельных фоновых задач

Я часто использую следующую команду для открытия редактора кода Lite-XL в фоновом режиме для текущего каталога:

lite . &

Аналогично, как известно, используется знак амперсанда (&) для выполнения любой команды как фоновой задачи. Можно объединить несколько команд с помощью & и запустить несколько фоновых задач следующим образом:

npm install & lite . &

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

Используйте оператор && с & следующим образом:

npm install && lite . &

Приведенный выше пример команды будет открывать редактор кода всякий раз, когда завершается команда npm install, не блокируя интерактивность терминала.


Использование стандартных команд Unix с конвейерами

Инженеры DevOps и системные администраторы часто имеют дело с удаленными серверными компьютерами, не оснащенными графическими интерфейсами. Между тем некоторые инженеры работают с ориентированными на графический интерфейс Unix и Unix-подобными системами. Но большинство из них, как правило, предпочитают CLI графическому интерфейсу. В некоторых сценариях разработки им приходится использовать различные вспомогательные команды для преобразования и анализа результатов работы других команд. Системы на базе и подобные Unix поставляются со встроенными стандартными вспомогательными командами, такими как wc, head, tail, sort, uniq, awk, sed и т. д.

Вы можете использовать эти команды вместе с оператором pipe для преобразования и анализа выходных данных команд. Например, для сортировки и дедупликации списка можно применить следующую комбинацию команд:

cat list.txt | sort -u

Для выделения сегментов строк можно объединить head и tail следующим образом:

cat list.txt | sort -u | tail -5 | head -3

Приведенная выше команда выводит отсортированные строки со 2 по 4. В качестве альтернативы (как более производительный вариант) можно использоватьsed:

cat list.txt | sort -u | sed -n "2,4p"

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

Читайте нас в TelegramVK и Дзен


Перевод статьи Shalitha Suranga: Unix/Linux Command Combinations That Every Developer Should Know

Предыдущая статьяПлюсы и минусы Deno
Следующая статьяKotlin: вложенный и внутренний классы