Количество хранимых команд определяется двумя переменными:
HISTSIZE
и HISTFILESIZE
. Первая определяет количество команд,
хранимых в памяти, вторая — в файле. Их уместно устанавливать
в ~/.bachrc
. Такие значения, мне представляются оптимальными:
HISTSIZE=5000
HISTFILESIZE=10000
По умолчанию, каждый экземпляр bash
переписывает историю.
То есть, если вы запустите два терминала, что-то в них сделаете,
а потом закроете, то история сохранится только от последнего
закрытого. (Она затрёт историю первого закрытого.) Это очень неудобно
и легко исправляется вот такой командой:
shopt -s histappend
которую тоже уместно написать в ~/.bachrc
.
Вся история:
history
Пять последних команд:
history 5
В сочетании с grep
:
history | grep cd
Но это всё только присказка.
Восклицательный знак выполняет команду с данным номером. Пример:
~$ ls -ld /bin
lrwxrwxrwx 1 root root 7 май 31 2013 /bin -> usr/bin
~$ history 3
4220 cd
4221 ls -ld /bin
4222 history 3
~$ !4221
ls -ld /bin
lrwxrwxrwx 1 root root 7 май 31 2013 /bin -> usr/bin
~$ echo !4221
echo ls -ld /bin
ls -ld /bin
Как видно из последней команды, подстановка с восклицательным знаком может быть частью другой команды. Она может быть использована в пайпе или в другом контексте. Примеры:
$ sudo !4221
$ !4221 >/dev/null
Номер может быть относительным, с конца: !-2
. Специальное сокращение
!!
— последняя команда.
Все знают о том, что по истории можно двигаться клавишами-стрелками.
Но иногда бывают ситуации, когда эти клавиши недоступны, работают
не правильно, или просто отсутствуют (у меня такое было, когда я
подключался каким-то ssh-клиентом с iPad). На этот случай полезно знать,
что промотка работает по Ctrl-p
и Ctrl-n
.
Режим поиск включается по Ctrl-r
. Для поиска следующего совпадения
надо повторно нажать Ctrl-r
. Для передвижения по совпадениям в другую
строну есть сочетание клавиш Ctrl-s
.
Проблема в том, что Ctrl-s
в большинстве терминалов приводит
к засыпанию. Чтобы выйти из сна, нажмите Ctrl-q
. Чтобы отключить
засыпание, есть команда:
stty -ixon
Bash (а вернее readline) поддерживает очень удобный стиль поиска — по
первым символам команды. К сожалению, по умолчанию, этот механизм
недоступен. Чтобы его включить, надо написать в ~/.inputrc
что-то такое:
# Shift-[Up][Down]
"\e[1;2A" history-search-backward
"\e[1;2B" history-search-forward
Теперь вы можете набрать начало команды и нажать Shift-<стрелка вверх>
.
И для вас будет найдена последняя команда из истории с таким же началом.
Стрелки с клавишей Shift
теперь позволяют двигаться по совпадениям.
Естественно, можно настроить любые другие клавиши.
Вы уже видели три простейшие подстановки:
!!
— последняя команда!n
— n-ная в истории команда (с номером n)!-n
— n-ная с конца командаПосле восклицательного знака можно указывать подстроку-начало команды.
!ls
— последняя команда ls
(со всеми аргументами).
Можно указывать подстроку для поиска:
!?encoder?
последняя команда с подстрокой encoder
.
Все слова (параметры разделённые пробелами) доступны через
модификатор :
(двоеточие). Пример:
$ cd /home
$ echo !!:1
echo /home
/home
Здесь !!
— ссылка на последнюю команду, а :1
ссылка на её
первый аргумент. Поэтому, в нашем примере echo !!:1
преобразуется
в echo /home
.
Для этого случая: когда мы оперируем именно с последней командой, можно опускать один восклицательный знак и двоеточие:
$ echo !1
Есть и привычные сокращения: первый аргумент — ^
, последний — $
,
все — *
. Имеются ввиду именно параметры команды. Без учёта самой
команды.
Следующий уровень модификаторов позволяет минимально управлять именами файлов.
Модификатор :t
даёт доступ к имени файла. Эта удобно скажем
в таком сценарии работы:
Вы обращаетесь к некому файлу, указывая полный путь:
cat /etc/hosts
Потом переходите в директорию с этим файлом
cd /etc
Выполняете ещё какие-то команды, а потом решаете отредактировать файл. Тогда вы можете написать так:
vi !cat:$:t
То есть, вы находите в историю последнюю команду cat
(!cat
),
берёте её последний аргумент :$
, а от него оставляете только
имя файла :t
.
Модификатор :h
работает противоположно, он отрезает имя файла,
оставляя весь остальной путь. Это полезно, например, когда вы
хотите перейти в директорию с последним просмотренным файлом:
vi /etc/hosts
cd $vi:$:h
Последняя команда перейдёт в директорию /etc
.
Последний модификатор из этой серии — :r
. Он отрезает расширение.
Его можно указывать несколько раз, есть вы хотите отрезать несколько
расширений (.tar.gz
).