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

Эта статья не обучит тебя, как пользоваться консолью, как объединять команды в пайпы и перенаправлять ввод-вывод. Она не о том, как писать скрипты или функции. Из нее ты не узнаешь, чем отличается bash от tcsh. Ее задача — показать тебе, как использовать консоль на всю катушку, добавить +50 к скорости ввода команд и +100 к эффективности. Поэтому новичкам стоит начать с базовых руководств или хотя бы изучить linux cheat sheet.

А мы, недолго думая, перейдем к делу.

 

Мигрируем на ZSH

Первое, что стоит сделать перед началом прокачки скиллов, — это избавиться от bash. Не потому, что он плохой или устаревший, а потому, что существует ZSH. Он неиллюзорно повысит твою продуктивность.

ZSH — очень сложный и комплексный командный интерпретатор. Полное руководство ZSH насчитывает около 800 страниц, а абсолютно все его функции, наверное, не знает никто. Но этого ни от кого и не требуют. На свете уже несколько лет существует проект oh-my-zsh, где пользователи создают набор скриптов, с помощью которых можно твикать и настраивать ZSH быстро и легко.

Чтобы получить стандартный набор твиков и настроек, включая мощный механизм автодополнения, информативное приглашение к вводу команды, настройки, повышающие удобство работы с ZSH, достаточно просто установить oh-my-zsh. Далее его можно обвешать плагинами для большего удобства работы с разными приложениями и поменять тему приглашения на любую из десятков, созданных пользователями.

Итак, для начала устанавливаем ZSH:

$ sudo apt-get install zsh

А затем скачиваем и устанавливаем oh-my-zsh:

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"

Скрипт установки клонирует git-репозиторий в каталог /home/username/.oh-my-zsh, добавит необходимые правки для вызова нужных скриптов в конфиг /home/username/.zshrc и запустит ZSH.

Устанавливаем oh-my-zsh
Устанавливаем oh-my-zsh

Теперь необходимо сделать ZSH шеллом по умолчанию:

$ sudo usermod -s /usr/bin/zsh имя_юзера

И перелогиниться, чтобы эмулятор терминала использовал ZSH в качестве дефолтового шелла. В качестве опционального шага ты можешь изменить тему. В комплект oh-my-zsh входит огромное количество тем, ознакомиться с которыми можно на wiki-странице. Чтобы выбрать новую тему, исправь значение переменной ZSH_THEME в файле ~/.zshrc. Выберем, например, тему agnoster:

ZSH_THEME="agnoster"
Тема agnoster
Тема agnoster
 

Перемещаемся по каталогам быстро

Одна из главных проблем консоли состоит в том, что ее неудобно использовать для перемещения по каталогам. Особенно если вложенных каталогов много, они имеют длинные имена, а еще хуже — похожие имена. В этом случае система автодополнения с помощью кнопки Tab помогает плохо и все, что остается, — это печатать имена каталогов руками.

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

$ cd ~/do

Затем нажать Tab и получить это:

$ cd ~/Downloads

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

Выбираем каталог
Выбираем каталог

В-третьих, автодополнение работает не только для начала имени каталога/файла, но и для любой его части. Чтобы перейти в каталог ~/Downloads, ты можешь набрать load и нажать Tab.

Наконец, в-четвертых, ZSH умеет дополнять имена каталогов по всему пути, а не только в последней его части. Это значит, что ты можешь напечатать нечто вроде этого:

$ cd /u/s/zs

Затем нажать Tab и получить это:

$ cd /usr/share/zsh

Более того, тебе совсем не обязательно печатать даже первые буквы имен каталогов. ZSH и bash умеют находить нужные каталоги самостоятельно, если они перечислены в переменной CDPATH. Добавь, например, следующую строку в ~/.zshrc:

export CDPATH=/var/www:/home/имя_юзера/Dropbox

Теперь, чтобы открыть каталог ~/Dropbox/Books, можно использовать такую команду:

$ cd Books

ZSH проверит, есть ли каталог Books в /var/www или /home/имя_юзера/Dropbox, и переместит тебя в него, если он существует.

 

Fasd

Есть и гораздо более мощное средство для перемещения между каталогами. Это утилита fasd (произносится как fast — быстрый). Она запоминает все каталоги (и просто пути к файлам), которые ты использовал, и позволяет перемещаться между ними, указав лишь часть пути (даже несколько букв).

Работает это так. Допустим, ранее ты переходил в каталог ~/src/projects/apps/myCoolApp и теперь, спустя часы или даже дни, хочешь в него вернуться. Все, что тебе необходимо сделать, — это выполнить такую команду:

$ z myCoolApp

Можно проще:

$ z CoolApp

И еще проще:

$ z Cool

Требование одно: указанный тобой набор символов должен быть уникальным среди всех путей, которые запомнил fasd. Кроме z, fasd поддерживает и другие шорткаты: a — показывает все сохраненные пути, zz — позволяет перейти в каталог, используя интерактивное меню (если введенный набор символов встречается в нескольких путях), v — открывает файл в редакторе Vim.

Утилита fasd доступна для Debian/Ubuntu, Arch Linux через AUR и для macOS через brew. Установить в Ubuntu можно так:

$ sudo add-apt-repository ppa:aacebedo/fasd
$ sudo apt-get update
$ sudo apt-get install fasd

Далее необходимо активировать плагин fasd в ~/.zshrc:

plugins=(git fasd)
 

Peco

Peco — еще один инструмент, способный сильно облегчить навигацию, а также поиск. Это небольшая утилита, которая принимает на вход список строк и выводит на экран псевдографическое меню, с помощью которого можно выбрать или найти нужную строку. Далее peco отдает эту строку на выход и завершает свою работу (по сути, это консольный аналог dmenu).

Peco можно использовать для навигации и поиска в любых текстовых строках, включая пути. Например, если ты запустишь следующую команду и выберешь каталог, peco напечатает его имя в терминале:

$ ls | peco

Не слишком удобно и полезно. Однако, немного усложнив пример, ты получишь интерактивный cd:

$ cd `ls | peco`

Польза появилась, удобство пострадало. Поэтому создадим для этой команды короткий и простой псевдоним. Для этого добавим следующую строку в ~/.zshrc:

alias cdi='cd `ls | peco`'

Теперь команда cdi будет запускать наш интерактивный cd.

Кстати, о самом cd. Запомни два простых правила:

  • команда cd без аргументов отправит тебя в домашний каталог;
  • команда cd — вернет в предыдущий каталог.

Peco
Peco

 

Используем автодополнение на полную катушку

Система автодополнения ZSH интересна не только своими интеллектуальными функциями, но и тем, что она работает не с одними именами каталогов и файлов. ZSH умеет дополнять флаги и опции многих утилит и выводить удобную справку по ним, умеет дополнять названия пакетов apt-get, yum, pacman и других пакетных менеджеров, дополняет имена хостов при подключении по SSH. Если набрать kill и нажать кнопку Tab, ZSH выведет список процессов. После второго нажатия Tab список станет интерактивным, и ты сможешь выбрать процесс, который следует умертвить.

Кроме встроенных правил автодополнения, on-my-zsh имеет множество плагинов с правилами автодополнения для многих утилит и приложений.

Kill Tab Tab
Kill Tab Tab

 

Работаем с историей команд

Любой современный командный интерпретатор, будь то ZSH или bash, сохраняет историю введенных команд. ZSH хранит историю в файле /home/username/.zsh_history. При необходимости его можно погрепать (grep ls ~/.zsh_history), чтобы найти нужную команду. Но делать это совсем не обязательно, ведь командный интерпретатор уже имеет в своем арсенале набор средств для работы с историей.

Например, следующая команда вставит в строку ввода предыдущую команду:

$ !!

Ее особенно удобно использовать, если забыл указать sudo перед командой, требующей права root:

$ pacman -Syu
error: you cannot perform this operation unless you are root.
$ sudo !!
sudo pacman -Syu

Можно взять из истории только аргумент команды. Например:

$ cd /home/user/foo
cd: /home/user/foo: No such file or directory
$ mkdir !*
mkdir /home/user/foo

А так можно вставить в строку ввода последнюю команду, начинающуюся с указанных символов:

$ !qwerty

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

$ !?qwerty?

Ты можешь даже исправлять описки в последней введенной команде:

$ ^dc^cd

С помощью комбинации Ctrl + R команды можно искать в интерактивном режиме. Просто начни вбивать символы, присутствующие в команде, и ZSH вставит в строку ввода нужную команду. Это очень удобная функция, но ее можно сделать еще удобнее, если использовать возможности уже знакомого нам peco.

В Сети можно найти сторонний плагин для oh-my-zsh под названием zsh-peco-history. Просто скачай его в каталог сторонних плагинов ZSH:

$ git clone https://github.com/jimeh/zsh-peco-history.git $ZSH_CUSTOM/plugins/zsh-peco-history

И активируй в ~/.zshrc:

plugins=(git fasd zsh-peco-history)

Теперь комбинация Ctrl + R будет запускать полноэкранное меню peco вместо однострочной поисковой строки.

 

Копируем, удаляем, переименовываем

Казалось бы, что может быть проще, чем скопировать или переименовать файл? Просто вбиваешь команду cp или mv, а затем старое и новое имена:

$ cp httpd.conf httpd.conf.bak

Но зачем утруждать себя, нажимая лишние кнопки, если можно сделать так:

$ cp httpd.conf{,.bak}

Строка, содержащая фигурные скобки с двумя строками, разделенными запятой, будет развернута в две строки, в одной из которых будут символы до запятой, а в другой — символы после.

Можно пойти дальше и использовать не просто замену строк, а регулярные выражения. Для этого нам понадобится команда rename:

$ rename 's/регулярка/на_что_заменить/' *.txt

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

Также стоит изучить команду basename. При обычном использовании она просто выводит последний элемент пути:

$ basename /usr/bin/zsh
zsh

Но также ее можно использовать для отрезания частей строки, например:

$ basename file.txt .txt
file

Ты можешь спросить, что это дает? А вот что:

$ for file in *.png; do convert "$file" "`basename "$file" .png`.jpg" ; done;

Это перекодировщик всех файлов PNG в JPG. Команда крайне проста: мы создаем цикл, который проходится по всем файлам PNG в текущем каталоге, затем запускает команду convert для перекодировки их в JPG. Basename здесь нужен для того, чтобы дать новым файлам корректное имя. Хинт: обратные кавычки запускают заключенную в себя команду в так называемом субшелле. Они нужны для запуска одной команды из другой.

Чтобы понять их мощь, обрати внимание на следующую команду:

$ rm -f `tar ztf /path/to/file.tar.gz`

Уверен, эта команда не раз спасет тебя, когда ты распакуешь архив tar.gz не в тот каталог. Она удаляет все ранее распакованные файлы.

 

Ищем правильно

Ты уже должен знать, что в любой UNIX-системе есть команда find, предназначенная для поиска файлов. Использовать ее предельно просто:

$ find . -name *.c -type f

Эта команда найдет все файлы с расширением .c в текущем каталоге и во всех его подкаталогах. Но что делать, если в каждом из этих файлов необходимо найти строку open? А вот это:

$ find -name *.c -type f | xargs grep open

Ищем open в файлах .c
Ищем open в файлах .c

Можно и несколько по-другому:

$ find . -name *.c -exec grep -H open {} ;

Этот пример немного сложнее и, как ни странно, медленнее. Почему? Потому, что xargs распараллелит поиск, запустив отдельный процесс grep на каждую строку.

При желании от find можно вообще избавиться:

$ grep -R open --include="*.c".

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

 

Работаем с буфером обмена

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

Однако в случае с терминалом у тебя есть один очень мощный инструмент. Он называется xclip и позволяет копировать и вставлять в буфер обмена. Для начала добавь в ~/.zshrc следующие строки и перезапусти терминал (или ZSH):

alias -g xcopy='xclip -selection clipboard'
alias -g xpaste='xclip -selection clipboard -o'

Теперь, чтобы что-то скопировать в буфер обмена, просто перенаправь вывод в xcopy. Например:

$ uname -a | xcopy

В буфере обмена окажется вывод команды uname -a. Вставить можно таким же образом:

$ xpaste

Вывод также можно перенаправить. Или заключить xpaste в обратные кавычки, чтобы его содержимое было выполнено шеллом.

 

Выводы

Командная строка не просто мощный инструмент. Это настолько мощный инструмент, что мне даже трудно придумать, какой тип интерфейса ОС может быть эффективнее. То, о чем я написал, — такая крошечная часть верхушки айсберга, что для описания всех трюков командной строки потребовалась бы серия книг, сродни «Большой советской энциклопедии». Ну а напоследок то, чего все так долго ждали, — dd с показом прогресса:

$ pv -tpreb /dev/sdb | dd of=~/sdb.img bs=1M

На этом все.

17 комментариев

  1. A.T.

    18.05.2017 at 14:14

    Никогда не понимал, почему в unix консоли так не плохо приживается файловый менеджер a-ля Нортон-коммандер, более известный как Far на сегодня. Midnight Commander надо специально ставить вручную и вручную же запускать. Под DOS-ом же без него было как без рук. В Юниксе любят трахаться с каталогами, напрягять память мозга, вводить дебильный -type f в команду find и жать Tab как можно чаще! Никогда этого не понимал. MC вообще не входит в стандартную поставку FreeBSD, хотя входит много других редкоземельных и ненужных в базовой инсталляции шлангов. Его надо специально ставить из портов да еще и искать в подкаталоге misc. Что касается чудовищно неудобного копирования, то в классическом unix за это как бы отвечала средняя кнопка мыши. Но детали я уже забыл. Неплохо было бы напомнить.

    • flekst

      18.05.2017 at 17:53

      напрягать память и руки не обязательно.
      alias findf=’find -type f’ решит вопрос

      Основная мощь шела не в поиске файлов, а в конвейерах

    • Илья Русанен

      18.05.2017 at 17:59

      `mc` не так нужен в Linux потому, что однострочники в bash c пайпами, аргументами и манипуляциями над ними позволяют значительно эффективнее проводить не только файловые операции, но и их поиск и модификацию. Эффективнее, чем `mc`. Сколько раз его ставил, ни разу не прижился ни на десктопе, ни на серверах. Оболочка DOS, насколько я помню, не предоставляет таких гибких возможностей, поэтому NC (или VC) — это необходимый инструмент. Это имхо)

  2. A.T.

    18.05.2017 at 14:17

    *так ПЛОХО приживается файловый менеджер*

  3. Илья Русанен

    18.05.2017 at 17:28

    Стоит доабвить, что команда `pv` дружит не только с dd, но и со другими утилитами — в них тоже можно вывести прогресс. Например, с tar (`tar -cf $DIR . | pv > $TARBALL`) или gzip (`pv $DIR | gzip > $GZIPBALL`). Также иногда может помочь утилита progress (`progress -mp $!`).

  4. flekst

    18.05.2017 at 17:50

    Никогда не понимал zsh. А уж если говорить об автокомплите, то нельзя забывать, например, такое:
    cd /v/w/l/h [tab] => cd /var/www/localhost/htdocs

    Большая часть работает во многих шеллах.
    Если уж ускоряться, то нельзя забывать хоткеи передвижения по командной строке. ^+[AEDFB] и другие. Именно этим меня и не устраивает автокомплит zsh. Для выбора надо переносить руки к стрелкам. Думаю, можно что-то найти типа vim-овского hjkl. Но нет смысла.

  5. hrapovd

    19.05.2017 at 11:29

    У меня не прижился zsh, вернулся на bash. Именно из-за того что я так не люблю в Windows — zsh и Windows пытаются думать за меня. bash — рулит!

    • flekst

      19.05.2017 at 11:44

      Башизмы — это плохо. Хочешь всё делать руками — лови чистый sh. Хотя, имхо это уже перебор.
      Лично я категоричен лишь в одном — идеального шела сейчас не существует.
      Каждому своё: sh, bash, dash, csh, tcsh, ksh, zsh, etc. У всех есть свои плюсы и минусы.

      • ruslantum

        26.05.2017 at 13:26

        еще fish есть 🙂 у меня именно он прижился, уж больно zsh замороченный в плане первичной настроики

  6. hrapovd

    22.05.2017 at 10:26

    В sh к сожалению не работают такие милые вещи как cp foo{,.bar}

  7. Asgoret

    22.05.2017 at 14:03

    Немного оффтопа.

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

  8. jura12

    28.06.2017 at 06:44

    в linux manjaro 17.0.2 алиасы должны быть без -g . и их можно поместить в ~/.bashrc .

    alias xcopy=’xclip -selection clipboard’
    alias xpaste=’xclip -selection clipboard -o’

    тогда пример работает.

    • flekst

      28.06.2017 at 10:14

      @jura12, дистрибутив не при чём. Читай маны
      Most other shells have aliases of this kind (command aliases). However, zsh also has global aliases, which are substituted anywhere on a line. Global aliases can be used to abbreviate frequently-typed usernames, hostnames, etc.

  9. kurand

    03.08.2017 at 00:04

    Извините, Евгений, но в статье не увидел «прокачки» терминала. Функционал linux utlities остается не зависимо от shell, примеры прикольные 🙂

  10. solarstrike

    13.08.2017 at 02:21

    Вата полная, гит не устанавливается

  11. enc

    17.11.2017 at 16:10

    Спасибо, статья понравилась. На zsh можно пепейти если еще не привыкши к fish в котором похожий функционал

Оставить мнение

Check Also

Windows 10 против шифровальщиков. Как устроена защита в обновленной Windows 10

Этой осенью Windows 10 обновилась до версии 1709 с кодовым названием Fall Creators Update …