Журнал LinuxFormat - перейти на главную

LXF123:DrBrown2

Материал из Linuxformat
Перейти к: навигация, поиск

Телепатия в оболочке

Bash Автодополнение – благо для тех из нас, кому трудно печатать аккуратно. Узнаем, как оно работает и как его расширить.


Из всех удобств Bash дополнение имени файла – едва ли не самое удобное (если вы не знаете, что это, см. врезку). Честно говоря, без него, для удаления, скажем, sussen_0.90‑feisty-1_i386.deb мне пришлось бы полдня концентрироваться, чтобы набрать все правильно. Но недавно я узнал, что возможности автодополнения шире. Это было случайное открытие. Я набрал нечто вроде sudo apt-get install и половины имени пакета и рассеянно нажал Tab – и вдруг увидел, что Bash и вправду дополнил мою команду. «Откуда, – удивился я, – Bash знает о программах, которые я хотел бы установить?».

Оказывается, в Bash есть всесторонний и расширяемый механизм дополнения. Во-первых, существует встроенная команда compgen, которая генерирует различные списки завершения. Частично они перечислены в таблице в конце.

Пример в действии: если набрать echo $E и нажать Tab, Bash дополнит имя переменной оболочки «EUID» на основе вывода команды compgen -v. Если ввести команду kill -H и нажать Tab, Bash дополнит имя сигнала «HUP» на основе вывода compgen -A signal.

Правила автодополнения (называемые «compspecs») добавляются в оболочку встроенной командой complete. При запуске Bash читает файл /etc/bash_completion, чтобы получить их (данный файл устанавливается по умолчанию не во всех дистрибутивах).

Вот простой пример из этого файла. Строка

complete -f -X ‘!*.@(exe|EXE|COM|scr|SCR|exe/so)’ wine

определяет правила для команды wine. Здесь сказано: «Сгенерировать список имен файлов, затем исключить те, что не соответствуют ни одному из шаблонов». Согласно этому правилу, Bash будет пытаться дополнять имена файлов для команды wine. Данный пример просто фильтрует вывод команды compgen -f.

Сделать больше

Механизм также можно расширить, передав ему либо пользовательские внешние программы, либо пользовательские функции, возвращающие список возможных совпадений, а затем определив их как правило командой complete.

Вернемся к той самой команде apt-get, которая меня удивила. Мой файл bash_completion содержит строку

complete -F _apt_get $filenames apt-get

Она велит Bash использовать функцию _apt_get для генерации списка возможных дополнений команды apt-get. Функция определена в одноименном файле. По существу, она выполняет команду apt-cache pkgnames, чтобы сгенерировать возможный список совпадений. Эта функция длинновата для рассмотрения здесь, поэтому разработаем пример попроще.

Его идея – в том, чтобы добавить дополнение аргумента для гипотетической команды eat, которая принимает как аргумент наименование пищи, например, eat яблоко. Я определил функцию _eat_complete для создания списка возможных блюд, а затем использовал команду complete -F для ее связи с командой eat.

Вот определение функции и соответствующей команды complete:

_eat_complete()
{
 cur=‘_get_cword’
 COMPREPLY=( $( compgen -W ‘абрикос апельсин банан
 яблоко’ -- $cur ))
}

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

COMPREPLY=( $( compgen -W ‘$(cat /etc/foods)’ -- $cur ))

Куда поместить это код? Ну, я мог бы добавить его в основной файл /etc/bash_completion. В порядке альтернативы, можно было бы поместить его в отдельный файл в каталоге /etc/bash_completion.d, и Bash найдет его там. Тогда более четко разграничатся системное автодополнение и мои игрушки. Поэтому я поместил его в файл /etc/bash_completion.d/eat. Потом – подумать только! – Bash начнет автодополнять аргументы команды eat. Конечно, чтобы подхватить новое правило, нужно запустить новую оболочку.

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

Параметры compgen

Введя Вы получите
compgen -b Встроенные команды оболочки
compgen -d Каталоги
compgen -c Имена команд
compgen -f Имена файлов
compgen -s Имена служб
compgen -v Имена переменных оболочки
compgen -A signal Имена сигналов

Узнать леденящие душу подробности можно на man-страницах Bash для встроенных команд ‘complete’ и ‘compgen

Персональные инструменты
купить
подписаться
Яндекс.Метрика