Содержание статьи
info
Ричарда Столлмана я, конечно, уважаю, но поднимать тему названия Linux vs GNU/Linux я в очередной раз не буду. Мы пишем Linux, ты понимай, как тебе ближе.
Консоль — это вовсе не проклятие Linux, а его главное достоинство. Пока ты не освоишь работу в ней, ты не поймешь философию Unix и будешь считать никсы недовиндой. Не нужно воспринимать эмулятор терминала как какой‑то архаичный интерфейс. Это и есть основной и вполне современный, а окошки — это надстройка.
Практически все, что можно делать в графике, можно делать и в консоли тоже. Да, тыкать мышкой легче, но, когда понадобится сделать сотни или тысячи однотипных действий, понимание консоли сразу же сэкономит тебе кучу времени.
Дальше я поделюсь советами, которые должны дать тебе понимание полезных концепций и научить образу действий. Я собираю разные трюки с консолью уже пятнадцать лет и хотел свести воедино самые полезные из них.
info
Базовые знания о Linux ты можешь почерпнуть из статьи «Linux за 30 минут. Руководство по выбору и использованию Linux для новичков». Мы же углубимся именно в работу с консолью и ее возможности.
Заметная часть повествования будет относиться к обработке текстов. Я буду давать много примеров из своей практики, а практика моя тесно связана с расчетами.
info
Большая часть квантово‑химического софта ориентирована на работу в консоли, и, если чуть поразмыслить, становится ясно почему. Ресурсы для подобных вычислений требуются порой фантастические, сами вычисления могут длиться днями и неделями. Само собой, машины, на которых это происходит, сугубо стационарные, а часто это кластеры. Визуальную оболочку на них обычно не ставят вовсе — за ненадобностью. К таким машинам не набегаешься, поэтому доступ обычно идет по SSH, причем держать тоннель поднятым днями и неделями неразумно. Поэтому типичный сценарий такой: подключаемся, запускаем процесс в фоне, результат пишем в файл, отключаемся, возвращаемся, когда посчитает, анализируем текстовый вывод.
Обустраиваемся
Чтобы ощутить все фишки консоли, для начала надо их активировать. В некоторых дистрибутивах «из коробки» настроены некоторые плюшки, но я буду исходить из того, что это не наш случай.
Перво‑наперво рекомендую в качестве оболочки поставить Zsh и включить автодополнение, подсветку синтаксиса и автообработку неизвестных команд с использованием pkgfile
. Темы и оформление уже можно выбирать по собственному вкусу, в инете полно готовых конфигов.
Подсветка синтаксиса облегчит визуальное восприятие, а автодополнение сделает работу быстрее. Достаточно набрать первые буквы, нажать Tab, и название команды или директории будет дополнено. Когда знаешь, где у тебя что лежит, добраться получается даже быстрее, чем с мышью.
Подсветку синтаксиса можно включить и в консольных текстовых редакторах, например nano. Тоже очень помогает в работе.
Циклы
Итак, Shell — это полноценный язык программирования, и, работая в консоли, очень удобно использовать однострочные скрипты. Например, используя цикл for, можно переименовывать файлы по шаблону:
#
$for
$ls
file0.txt
file10.txt
file1.txt
file2.txt
file3.txt
file4.txt
file5.txt
file6.txt
file7.txt
file8.txt
file9.txt#
$for
$ls
file0.png
file10.png
file1.png
file2.png
file3.png
file4.png
file5.png
file6.png
file7.png
file8.png
file9.png
В этом примере можно увидеть сразу несколько удобных приемов. Во‑первых, перебор чисел от 0 до 10 (for
) и использование данных значений для именования файлов (touch
). Во‑вторых, оформление блоков кода (от do
до done
).
info
Синтаксис в разных диалектах Shell несколько различается. Все представленное здесь справедливо для Zsh и Bash — их синтаксис совместим. Однако в других оболочках (например, Fish или Elvish) некоторые конструкции могут не работать.
В‑третьих — использование маски *txt
, по которой подставляются имена всех файлов в данной директории, оканчивающихся на txt
. При помощи маски мы из множества файлов выбираем некоторые, подпадающие под шаблон.
Глобы и регэксы
Маски (они же «шаблоны подстановки» или «глобы», glob) — это самый простой вид задания паттернов. Их синтаксис прост: ?
— один любой символ, *
— любое число любых символов, [
— один из перечисленных, [
— один символ из диапазона плюс еще несколько подобных правил.
Существует более продвинутая версия — регулярные выражения (regex). Их уже можно использовать для поиска и замены паттернов практически любой сложности. В Bash, чтобы узнать, подпадает ли строка под паттерн, заданный регулярным выражением, используется специальный оператор =~
. Например: [[
.
Однако в Bash реализация регэксов неполная. Если понадобится вся их мощь, лучше обратиться к специальным командам вроде grep
, sed
и awk
(их можно вызвать прямо из Bash — об этом ниже) и скриптовым языкам типа Perl и Python. Также регулярки можно использовать для поиска и замены текста во многих редакторах кода — от vi до VS Code.
Ну и последнее — это работа со строками. Конструкция ${
означает, что оператор %
ищет совпадение с шаблоном, начиная с конца строки, и удаляет найденные фрагменты. Если использовать оператор #
, то поиск будет идти с начала.
Обрати внимание, что в этом выражении значение переменной подставляется так: сначала знак доллара, а затем имя переменной в фигурных скобках. Это может быть непривычно в сравнении с другими языками программирования. Ну а текст png
просто дописывается в конец, независимо от результата обработки строки.
Название «однострочные скрипты» (или «однострочники») весьма условное: здесь вместо новой строки просто используется точка с запятой, что позволяет объединить три строки в одну. Так можно собрать длинную последовательность команд и потом вставлять в терминал одной строкой. Но если строка выходит совсем уж громоздкой, лучше оформить ее как отдельный скрипт. Так будет проще править и отлаживать. Да и кровь из глаз не пойдет.
warning
При написании однострочных скриптов, занимающихся переименованием, удалением и другими потенциально необратимыми действиями, крайне полезно сделать первый холостой запуск. Например, добавив перед целевой командой echo
. Это позволит проверить, все ли работает так, как ожидается. В особо ответственных случаях стоит и о бэкапе подумать. Помни — лишний пробел в удачном месте при удачном стечении обстоятельств может снести половину системы, как было в свое время с обновлением «Яндекс Диска». Будь внимателен!
Unix-way
Концепция «все есть файл» в Unix-системах неразрывно связана с перенаправлением вывода и пайпами (они же «трубы» и «конвейеры»). Собственно, эти механизмы и позволяют реализовать принцип KISS (keep it simple, stupid — «делай проще, дурачок»). Заключается он в том, что в системе много отдельных утилит, каждая из которых делает хорошо что‑то одно, а вместе из них можно собрать сколь угодно сложные и мощные комбинации.
Например, в командных интерпретаторах есть замечательная функция вызова предыдущих команд с помощью стрелок вверх и вниз. Крайне удобная штука: позволяет не заучивать все используемые команды. Достаточно один раз составить и выполнить команду, и она запишется в истории, а потом, если понадобится, можно будет вызвать ее в несколько кликов.
А что делать, если команда использовалась давно? Проматывать историю из десятков команд неудобно. Но история команд — это просто файл ~/.
: его можно посмотреть вручную или использовать утилиту history
, которая выводит список из десятка последних команд с их номерами.
Удобно: взглянул на список, нашел нужную строчку, даже копировать не надо. Просто набираем !
, жмем Enter, и команда вновь выполнится. А если нажать Tab, то развернется до удобного для чтения вида, и ее можно будет подредактировать при необходимости.
А если команда далеко в истории? Нет проблем, используем history
, где N — число предыдущих команд, которые надо отобразить. Так можно проследить вплоть до установки системы.
Впрочем, искать команду глазами в огромной портянке текста не всегда удобно, а у терминалов обычно буфер строк ограничен несколькими сотнями...
Пайпы
Тут нам помогут пайпы и утилита grep
! Представим, что ты вспомнил часть команды и хочешь поискать по этой строке. Например, можем по строке for
поискать скрипт, который мы писали в начале статьи.
history -10000|grep "for i"
...
11654 for i in {0..10};do touch file"i".txt;done
11657 for i in *txt;do echo i {i%txt}png;done
11658 for i in *txt;do mv i ${i%txt}png;done
Утилита grep ищет строки, подходящие под шаблон. Здесь, кстати, используются уже не просто маски, а полноценные регулярные выражения.
Символ пайпа |
тут передает вывод команды history
на ввод утилиты grep
— это и есть пайп. Хочешь в найденном поискать еще раз? Просто добавляешь еще пайп и еще grep
с новым шаблоном! И так можно соединять сколько угодно раз и любые команды.
Перенаправление вывода и tee
Еще ты можешь перенаправить вывод команды в файл. Например, если в конце нашего поиска добавить >
, то вывод вместо отображения в консоли будет записан в указанный файл. Если нужно дописать в файл, не трогая его содержимое, то используются уже две треугольные скобки — например, echo
.
А что, если нужно и выводить на экран, и писать в файл? Для этого есть замечательная утилита tee. Без параметров она создаст новый файл, а с ключом -a
допишет в существующий.
Продолжение доступно только участникам
Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте
Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», позволит скачивать выпуски в PDF, отключит рекламу на сайте и увеличит личную накопительную скидку! Подробнее
Вариант 2. Открой один материал
Заинтересовала статья, но нет возможности стать членом клуба «Xakep.ru»? Тогда этот вариант для тебя! Обрати внимание: этот способ подходит только для статей, опубликованных более двух месяцев назад.
Я уже участник «Xakep.ru»