Опубликован: 22.06.2005 | Уровень: для всех | Доступ: платный | ВУЗ: Компания IBM
Лекция 8:

Возможности командной оболочки

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >

История команд

Двумя другими клавишами со стрелками - вверх и вниз - Мефодий тоже активно пользовался, не подозревая, что задействует этим весьма мощный механизм bash - работу с историей команд. Все команды, набранные пользователем, bash запоминает и позволяет обращаться к ним впоследствии. По стрелке вверх (можно использовать и " ^P ", previous), список поданных команд "прокручивается" от последней к первой, а по стрелке вниз (" ^N ", next) - обратно. Соответствующая команда отображается в командной строке как только что набранная, ее можно отредактировать и подать оболочке (подгонять курсор к концу строки при этом необязательно).

Если необходимо добыть из истории какую-то давнюю команду, проще не гонять список истории стрелками, а выполнить поиск с помощью команды " ^R " (reverse search). При этом выводится подсказка специального вида ("reverse-i-search"), подстрока поиска (окруженная символами ` и ' ) и последняя из команд в истории, в которой эта подстрока присутствует:

[methody@localhost methody]$
 ^R | (reverse-i-search)`':
 i  | (reverse-i-search)`i': ls i
 n  | (reverse-i-search)`in': info
 f  | (reverse-i-search)`inf': info
 o  | (reverse-i-search)`info': info
 ^R | (reverse-i-search)`info': man info
 ^R | (reverse-i-search)`info': info "(bash.info.bz2)Commands For History"
Пример 8.3. Поиск по истории команд

Пример представляет символы, вводимые Мефодием (в левой части до " | "), и содержимое последней строки терминала. Это "кадры" работы с одной и той же строкой, показывающие, как она меняется при наборе. Набрав "info", Мефодий продолжил поиск этой подстроки, повторяя " ^R " до тех пор, пока не наткнулся на нужную ему команду, содержащую подстроку " info ". Осталось только передать ее bash с помощью Enter.

Чтобы история команд могла сохраняться между сеансами работы пользователя, bash записывает ее в файл .bash_history, находящийся в домашнем каталоге пользователя. Делается это в момент завершения оболочки: накопленная за время работы история дописывается в конец этого файла. При следующем запуске bash считывает .bash_history целиком. История хранится не вечно, количество запоминаемых команд в .bash_history ограничено (обычно сохраняется 500 команд, но это можно и перенастроить).

Сокращения

Поиск по истории - удобное средство: длинную командную строку можно не набирать целиком, а отыскать и использовать. Однако давнюю команду придется добывать с помощью нескольких " ^R " - а можно и совсем не доискаться, если она уже выбыла оттуда. Для того чтобы оперативно заменять длинные команды короткими, стоит воспользоваться сокращениями (aliases). В конфигурационных файлах командного интерпретатора пользователя обычно уже определено несколько сокращений, список которых можно посмотреть с помощью команды alias без параметров:

[methody@localhost methody]$ alias
 alias cd..='cd ..'
 alias cp='cp -i'
 alias l='ls -lapt'
 alias ll='ls -laptc'
 alias ls='ls --color=auto'
 alias md='mkdir'
 alias mv='mv -i'
 alias rd='rmdir'
 alias rm='rm -i'
Пример 8.4. Просмотр заранее определенных сокращений

С сокращениями Мефодий уже сталкивался в примерах, приведенных в лекции 6, где команда ls отказалась работать в согласии с теорией. Выяснилось, что по команде ls вместо утилиты /bin/ls bash запускает собственную команду-сокращение, превращающееся в команду ls --color=auto. Повторно появившуюся в команде подстроку " ls " интерпретатор уже не обрабатывает, во избежание вечного цикла. Например, команда ls -al превращается в результате в ls --color=auto -al. Точно так же любая команда, начинающаяся с rm, превращается в rm -i (interactive), что Мефодия крайне раздражает, потому что ни одно удаление не обходится без вопросов в стиле " rm: удалить обычный файл `файл'?":

[methody@localhost methody]$ unalias cp rm mv
[methody@localhost methody]$ alias pd=pushd
[methody@localhost methody]$ alias pp=popd
[methody@localhost methody]$ pd /bin
 /bin ~
[methody@localhost bin]$ pd /usr/share/doc
 /usr/share/doc /bin ~
[methody@localhost doc]$ cd /var/tmp
[methody@localhost tmp]$ dirs
 /var/tmp /bin ~
[methody@localhost tmp]$ pp
 /bin ~
[methody@localhost bin]$ pp
 ~
[methody@localhost methody]$ pp
 -bash: popd: directory stack empty
Пример 8.5. Использование сокращений и pushd/popd

От надоедливого " -i " Мефодий избавился с помощью команды unalias, а заодно ввел сокращения для полюбившихся ему команд bash - pushd и popd. Эти команды2Они названы по аналогии с операциями работы со стеком - pushd и popd ., подобно cd, меняют текущий каталог. Разница состоит в том, что pushd все каталоги, которые пользователь делает текущими, запоминает в особом списке (стеке). Команда popd удаляет последний элемент этого стека и делает текущим каталогом предпоследний. Обе команды вдобавок выводят содержимое стека каталогов (то же самое делает и команда dirs ). Команда cd в bash также работает со стеком каталогов: она заменяет его последний элемент новым.

Команда-сокращение (alias) - внутренняя команда shell, задаваемая пользователем. Обычно заменяет одну более длинную команду, которая часто используется при работе в командной строке. Сокращения не наследуются с окружением .

Достраивание

Сокращения позволяют быстро набирать команды, однако никак не затрагивают имен файлов, которые чаще всего и оказываются параметрами этих команд. Бывает, что набранной строки - пути к файлу и нескольких первых букв его имени - достаточно для однозначного указания на этот файл, потому что по введенному пути других файлов, чье имя начинается на эти буквы, просто нет. Чтобы не дописывать оставшиеся буквы (а имена файлов в Linux могут быть весьма длинными), Гуревич посоветовал Мефодию нажать клавишу Tab. И - о чудо! - bash сам достроил начало имени файла до целого (снова воспользуемся методом "кадров"):

[methody@localhost methody]$ ls -al /bin/base
 Tab  | [methody@localhost methody]$ ls -al /bin/basename
-rwxr-xr-x  1 root root 12520 Июн  3 18:29 /bin/basename
[methody@localhost methody]$ base
 Tab    | [methody@localhost methody]$ basename
 Tab    | [methody@localhost methody]$ basename ex
 Tab    | [methody@localhost methody]$ basename examples/
 Tab    | [methody@localhost methody]$ basename 
examples/-filename-with-
-filename-with-
Пример 8.6. Использование достраивания

Дальше - больше. Оказывается, и имя команды можно вводить не целиком: оболочка достроит набираемое слово именно до команды, раз уж это слово стоит в начале командной строки. Таким образом, команду basename examples/-filename-with- Мефодий набрал за восемь нажатий на клавиатуру (" base " и четыре Tab )! Ему не пришлось вводить начало имени файла в каталоге examples, потому что файл там был всего один.

Выполняя достраивание (completion), bash может вывести не всю строку, а только ту ее часть, относительно которой у него нет сомнений. Если дальнейшее достраивание может пойти несколькими путями, то однократное нажатие Tab приведет к тому, что bash растерянно пискнет3Все терминалы должны уметь выдавать звуковой сигнал при выводе управляющего символа " ^G ". Для этого не нужно запускать никаких дополнительных программ: "настоящие" терминалы имеют встроенный динамик, а виртуальные консоли обычно пользуются системным ("пищалкой"). В крайнем случае разрешается привлекать внимание пользователя другими способами: например, эмулятор терминала screen пишет в служебной строке "wuff-wuff" ("гав-гав")., а повторное - к выводу под командной строкой списка всех возможных вариантов. В этом случае надо подсказать командной оболочке продолжение: дописать несколько символов, определяющих, по какому пути пойдет достраивание, и снова нажать Tab.

Поиск ключевого слова "completion" по документации bash выдал так много информации, что Мефодий обратился к Гуревичу за помощью. Однако тот ответил, что не использует bash, и поэтому не в состоянии объяснять тонкости его настройки. Если в bash предусмотрено несколько типов достраивания (по именам файлов, по именам команд и т. п.), то в zsh их сколько угодно: существует способ запрограммировать любой алгоритм достраивания и задать шаблон командной строки, в которой именно этот способ будет применяться.

< Лекция 7 || Лекция 8: 123456 || Лекция 9 >
Аягоз Имансакипова
Аягоз Имансакипова
Тимур Булатов
Тимур Булатов

С момента выхода курса прошло достаточно много времени, и хотелось бы понимать, насколько курс является актуальным на сегодняшний день.