Перевод статьи «6 Command Line Tools for Productive Programmers».
В последнее время я очень много чего делаю в командной строке. Не то чтобы я был горячим поклонником работы в терминале. Скажем, VSCode я пользуюсь куда больше, чем Vim. Но меня всегда поражало, как много сложных задач можно решить, применяя стандартные инструменты командной строки, такие как grep, cat и sort.
Инструменты — это важно. Хороший инструмент позволяет выполнить работу проще и быстрее. Отличный инструмент раскрывает перед вами новые возможности: то, что еще недавно казалось невозможным, становится легкой задачей.
Мой набор инструментов командной строки постепенно пополняется, и в этой статье я расскажу о нескольких, которые мне кажутся наиболее ценными и интересными.
broot
Я уж и не вспомню, как я вышел на broot, но этот инструмент невероятно удобен.
Если вы находитесь в маленькой директории и хотите осмотреться в ней, вам прекрасно подойдет команда tree.
✗ tree . ├── dartboard.png ├── header.jpg ├── opensign.png ├── quote1.png └── trophy.png 0 directories, 5 files
Но если директория содержит много файлов и поддиректорий, tree становится куда менее полезной: все, что вы увидите, это последний экран с кучей файлов, а все остальные файлы просто проскользнут вверх.
$ tree < долгая-долгая прокрутка > ├── banner.js └── index.html 328 directories, 2028 files
broot решает эту проблему, подгоняя выдачу под размер вашего терминала.
Вы можете перемещаться по результатам, используя клавиши со стрелками. Если передать команде флаг -w
(broot -w
), можно будет увидеть и то, сколько дискового пространства занимают директории.
Вообще с помощью команды broot можно делать множество других вещей, так что загляните в гайд на GitHub. Но лично я чаще пользуюсь этой командой просто как улучшенной версией tree.
Установка
На MacOS эту команду можно установить с помощью brew. Все другие инструкции по установке можно почитать здесь.
brew install broot
Funky
Если вы живете в терминале и хотите использовать его в качестве среды разработки, вам будет полезна возможность подгонять терминал под свои нужды в зависимости от текущей директории. Сделать это можно многими способами.
DirEnv загружает и выгружает .env-файлы при входе в директории.
smartcd имеет аналогичный функционал. Эта библиотека позволяет запускать shell-скрипт при переходе по определенному пути. Таким образом можно запускать и останавливать сервисы, менять приглашение командной строки и т. п.
Но из всех инструментов этой категории мой фаворит — funky.
Funky «поднимает shell-функции на новый уровень, облегчая их определение и делая их более гибкими и более интерактивными».
Работает funky просто. Вы входите в директорию, funky ищет .funky-файл, содержащий список bash-функций. Затем он эти функции загружает, а когда вы выходите — выгружает обратно.
Это означает, что когда я нахожусь в директории этого блога, у меня есть загруженные алиасы для создания нового поста, линтинга markdown-разметки, вытягивания картинок и т. д. Я могу вывести их список, введя команду funky.
$ funky lint() { markdownlint --fix "./_posts/*.md"; } set-header() { cp "$(latest-image)" "$(image-folder)/header.jpg"; } set-image() { cp "$(latest-image)" "$(image-folder)/$(date +%s).png"; }
Вообще funky может делать и другие вещи. У него есть функционал для интерактивного добавления и редактирования функций, для регистрации глобальных функций и алиасов. Но лично мне нравится просто возможность быстро задать командам короткие псевдонимы, зависящие от контекста.
Установка
Funky можно установить с помощью pip.
pip3 install pyfunky
Затем добавьте следующую строку в ваш .zshrc, bashrc или аналогичный файл:
## найдите, куда pip установил funky.sh, и укажите этот путь в качестве источника source /usr/local/lib/python3.9/site-packages/scripts/shell/funky.sh
Fuzzy Finder (FZF)
Раз funky и broot увеличили мою продуктивность, значит, другие инструменты могут увеличить ее еще больше, верно? На сайте вопросов и ответов я спросил, какими инструментами вообще люди пользуются. FZF довольно часто мелькал в ответах, так что я решил тоже попробовать.
FZF — инструмент командной строки для нечеткого поиска. Он позволяет быстро и интерактивно отфильтровать варианты, основываясь на нечетких ключевых словах.
Установив включенные сокращения (/usr/local/opt/fzf/install
), вы сможете использовать **
, чтобы задействовать интерактивный нечеткий поиск в любом месте. Помимо всего прочего, FZF ускоряет поиск по history.
По сути это unix-фильтр, который считывает входные данные, показывает интерактивный список, который вы фильтруете, а затем отправляет выбранный элемент на другую сторону. Беда в том, что это описание не отражает всю полезность FZF. Поэтому я советую посмотреть видео Алексея Самошкина, где показано много разных способов использования FZF (на фоне приятной тихой музыки).
Установка
Вы можете установить FZF через свой любимый менеджер пакетов:
brew install fzf
Затем добавьте хуки в ваш файл .zshrc, bashrc или аналогичный:
#ZSH source ~/.fzf.zsh #BASH source ~/.fzf.bash
McFly
FZF отлично подходит для фильтрации путей к файлам в командной строке, когда вам нужно открыть файл (vim **
). Но что касается дополнения в самой командной строке, лучше использовать McFly. Этот инструмент для предоставления более релевантных результатов пытается учитывать дополнительную информацию, не только из файла history.
Что это за дополнительная информация? При построении рейтинга вариантов McFly оценивает следующие сведения:
- команды, которые вы вводили до этой команды
- частота запуска команды
- насколько давно вы вводили команду.
Все это он отслеживает в базе данных SQLite. При этом он также оценивает и другие вещи:
- статус выхода команд
- директория, в которой вы запускаете команду
- выбирали ли вы эту команду в McFly ранее.
Мне не нравится, когда мне предлагают нерабочие команды, но я никогда не думал о возможности сужать поиск, основываясь на текущей директории, или понижать рейтинг команд, которые я никогда не выбираю.
Для ранжирования McFly использует нейронную сеть. Единственный минус этого подхода — задержка предложений, если база данных SQLite слишком велика. Но ее рост можно ограничить при помощи MCFLY_HISTORY_LIMIT
.
Сам я пользуюсь этим инструментом всего пару дней, так что не могу ручаться за его полезность. Однако сама концепция обнадеживает: использование большего количества информации для кастомизации инструментов — шаг в правильном направлении.
Установка
Установить McFly можно разными способами. Вот установка через brew:
brew tap cantino/mcfly
Затем надо добавить строку в .zshrc, bashrc или аналогичный файл:
eval "$(mcfly init zsh)"
Мелочь, а приятно: двоичный файл генерирует init-скрипт, а не сбрасывает его в мою домашнюю директорию. zoxide — следующий инструмент — делает так же.
Я обнаружил, что FZF конфликтует с CTRL-R McFly, и, чтобы McFly заработал, мне пришлось закомментировать эту строку в init-скрипте FZF.
Улучшаем cd
FZF хорошо работает для дополнения путей, но не слишком полезен при смене директорий при помощи cd.
Скажем, если я, находясь в домашней директории, ввожу cd **TAB
, на создание полного списка возможных опций уходит некоторое время. Получается, что для навигации по папкам удобнее пользоваться функционалом ZSH: cd TAB <выбрать-директорию> TAB <выбрать-директорию>
.
Но есть много инструментов, призванных улучшить работу cd. Например, autojump, z и Fasd отслеживают использование директорий и предоставляют одноклавишный шорткат для перехода в те из них, которыми вы пользуетесь часто.
На r/commandline есть подробное обсуждение всех этих альтернатив cd. Самый интересный из вариантов — zoxide.
zoxide — это реплика z, написанная на Rust. Достоинство этого инструмента — более высокая скорость работы.
После установки вы можете использовать zoxide точно как cd:
z ~/path/foo/bar
Но можно также переходить по директориям, основываясь на ранжированных совпадениях с указанным словом в пути:
z bar ~= cd ~/path/foo/bar
Вместо необходимости вводить полный путь, можно ввести уникальную подстроку, имеющуюся в этом пути, и zoxide использует историю команд, чтобы вы получили желаемый путь.
Чтобы было проще привыкнуть к команде, я решил заменить cd на zoxide. Сделать это просто, нужно лишь использовать флаг --cmd
при добавлении оболочки инициализации (eval "$(zoxide init zsh --cmd cd)"
).
Установка
zoxide можно установить разными способами. Вот пример установки через brew:
brew install zoxide
После этого нужно добавить строку в .zshrc, bashrc или аналогичный файл:
eval "$(zoxide init zsh --cmd cd)"
GitUpdate
Еще один инструмент, найденный на сайте с вопросами и ответами.
Работая над веткой в git, я предпочитаю делать коммиты почаще. Например, прежде чем удалить какой-то большой кусок текста в статье или приступить к рефакторингу большого куска кода, я делаю коммит свой работы.
Конечно, потом я эти коммиты могу убрать или реструктуризировать. Но для удобства у меня есть git-алиас wip («work in progress»), благодаря которому я могу легко сделать коммит.
git wip = !git add --all; git ci -m WIP
gitupdate — простое улучшение этой идеи. Команда gitupdate .
коммитит ваши файлы, а для создания более осмысленных сообщений коммитов использует имена измененных файлов (но не их расширения). Это отличный вариант для случаев, когда сообщение коммита не имеет значения.
Установка
bash git clone https://github.com/nikitavoloboev/gitupdate go build sudo cp gitupdate /usr/local/bin
Другие инструменты
Существует много других полезных инструментов командной строки. Их куда больше, чем можно вместить в одну статью. Например, я часто пользуюсь JQ, mitmproxy, Pandoc и PSTree. Есть также целый класс POSIX-инструментов, переписанных на Rust — они заслуживают отдельной статьи.
А какими не слишком распространенными инструментами командной строки вы пользуетесь? Если есть, что предложить, — добро пожаловать в комментарии!
[customscript]techrocks_custom_after_post_html[/customscript]
[customscript]techrocks_custom_script[/customscript]