Поиск предыдущей команды с префиксом, который я только что набрал


67

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

В некоторых IDE, таких как Matlab, если мы что-то вводим, а затем нажимаем клавиши со стрелками, мы прокручиваем только те команды истории, которые начинаются с того, что мы ввели. Это действительно удобно, но в терминале оболочки это не работает.

Есть ли способ получить подобную функцию в терминале оболочки? И какие еще советы по повышению эффективности использования терминала?


Вы можете просто использовать оболочку, которая предоставляет такую ​​функцию, как fish;)
yoann

@yoann ты предполагаешь, что bash нет. Через readline он по умолчанию недоступен.
Муру

@muru Я знаю, что такое CTRL + R в bash, и ответ egmont предоставляет отличный способ сделать это с помощью Page Up / Page Down. Есть ли способ сделать это с помощью клавиш со стрелками?
2015 года

1
@yoann проверить unix.stackexchange.com/a/76591/70524 . Вместо того , \e[5~и \e[6~, использования \e[A, \e[B.
Муру

Ответы:


95

То, что вы ищете, это CtrlR.

Введите, CtrlRа затем введите часть команды, которую вы хотите. Bash отобразит первую соответствующую команду. Продолжайте печатать, CtrlRи bash будет циклически повторять предыдущие соответствующие команды.

Чтобы выполнить поиск в истории, введите CtrlSвместо этого. (Если у вас CtrlSэто не работает, это, вероятно, означает, что вам нужно отключить управление потоком XON / XOFF: для этого запустите stty -ixon.)

Это задокументировано в разделе «Поиск» в man bash.


1
Ctrl-Qвыйти из замороженного состояния, если вы уже нажали, Ctrl-Sне отключив сначала управление потоком, и заморозили свой терминал.
ХунбоЖу

26

Разместите их в своем ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Они делают Page Upи Page Downведут себя, как вы хотите. (В некоторых дистрибутивах он уже настроен для вас.) Лично я нахожу эти способы более удобными, чем Ctrl+ Rили history.


Это самый удобный способ во всех текущих ответах. Не могли бы вы дать небольшое объяснение о работе механизма?
Ли

3
~/.inputrcили /etc/inputrcили файл, на который ссылается переменная среды, $INPUTRCявляется файлом конфигурации редактирования строки всего приложения, использующего readline, включая bash (вашу оболочку). Он имеет определенные встроенные возможности редактирования строк, включая эти два: в справочной странице bash найдите одно из этих ключевых слов, чтобы узнать больше. \e[5~/ \e[6~- escape-последовательности, генерируемые клавишами Page Up / Down в большинстве эмуляторов терминала; чтобы увидеть его, запустите catкоманду и затем нажмите эти клавиши (управляющий байт представлен в терминале как ^[, в inputrc как \e).
egmont

Пример в вашем первоначальном вопросе говорит, что клавиши «вверх» и «вниз» работают таким же образом в Matlab. Было бы интересно посмотреть, что произойдет, если вы поместите последовательность Up и Down в inputrc и назначите это действие; будет ли он работать правильно, или иметь неприятные побочные эффекты, так как он конфликтует с их поведением по умолчанию. Я не знаю, я был бы рад услышать ваши выводы, если вы поэкспериментируете с этим.
egmont

Когда я делаю echo $INPUTRCэто пусто. Я использую Ubuntu 14.04
JorgeeFG,

2
Я лично предпочитаю переопределять стрелки вверх и вниз, чтобы сделать это: "\e[A": history-search-backwardи"\e[B": history-search-forward
A.Wan

9

Помимо истории ^ r / ^ s i-search:

alt.вставляет последнее «слово» предыдущей команды в курсор. Повторите это, чтобы получить последнее слово от старых команд. (Но обратите внимание, что конечный текст &считается последним словом для фоновых команд).

Это супер удобно для mkdir foo, cdalt-dot. Даже быстрее , чем стрелка вверх, ^ а, альт-D (удаление вперед слово) cd.

Чтобы получить второе-последнее слово, используйте esc - 2 alt+.(т. Е. Используйте числовой аргумент в стиле emacs для alt+.. Отрицательный счет с конца, положительный счет от начала.) Но обычно это больше проблем, чем стоит; в какой-то момент быстрее добраться до мыши и скопировать / вставить, или стрелку вверх и ^ w / ^ y ее часть (см. ниже).


Если ваш терминал настроен правильно / правильно, ctrl-left и ctrl-right будут идти вперед / назад по словам. Если нет, то, по крайней мере, alt-b и alt-f сделают то же самое.


Ctrl- / это отмена. Вы можете использовать автоповтор для более эффективного удаления слов, если вы можете отменить, когда вы немного отклонитесь от нормы.


Более мощное смешивание / сопоставление команд происходит благодаря использованию kill-ring, который работает так же, как в Emacs. Ctrl-Y, чтобы вставить последний Ctrl-W / Ctrl-U / Ctrl-Backspace / Alt-D. alt-y для циклического перебора старого убитого текста.

Множество ctrl-w или что-то подряд делает запись в kill-ring. Используйте стрелку влево и вправо или что-то, чтобы разбить запись, если вы хотите удалить две вещи и вставить только одну позже.

Объединяя все это вместе, вы можете

  • начать вводить команду
  • Ctrl-r, чтобы вернуться к старой команде и взять ее часть с помощью control-w или чего-то подобного.
  • esc-r или alt+rвосстановить его до того, как вы удалили его часть.
  • alt >- перейти в конец истории (т. е. всю стрелку вниз), чтобы вернуться к команде, в которой вы находились.

Другие интерактивные советы по использованию:

Включить shopt -s globstar, так что вы можете сделать **/*.c(рекурсивный, включая текущий каталог). Иногда удобно для интерактивного использования, но обычно find -name '*.c' -exec foo {} +лучше.

Если вы будете писать скрипты bash, вам будет удобно shopt -s extglobвключить их и в интерактивных оболочках. Вы иногда находите применение для таких вещей , как , *.!(c|h)чтобы соответствовать файлам , которые не заканчиваются на .c или .h.

Найти псевдонимы вы любите для ls -l, lessи все , что вы делаете много. ( cp -i, mv -iи rm -Iэто хорошо. Не имейте привычки зависеть от них, чтобы сделать выборочный rm. GNU rm's -I спрашивает один раз для всех аргументов.)

Мне нравится alias m=less(м для «больше»). Я lessустановил ,и .привязал к предыдущему / следующему файлу ( lesskey). По умолчанию используется последовательность нажатий нескольких клавиш, которую нельзя использовать с автоповторением.


Мне нравится делать все внутри экрана GNU. Я считаю, что легче отслеживать пронумерованные окна, чем множество вкладок в Konsole (или любом другом эмуляторе терминала, который я пробовал). Если вы еще не знаете screen, изучите tmux, потому что он более новый и менее хитрый.

Чтобы получить что-то похожее на функциональность открытия новой оболочки с тем же cwd, что и у другой оболочки, я использую пользовательский хук для cd / pushd / popd, который позволяет мне делать cds 8cd на любой каталог, который использует моя оболочка в экранном окне 8. Это работает даже для оболочек вне сеанса экрана, если только один сеанс экрана.


Мой, похоже, не "правильно настроен". Многие ярлыки, которые я вижу здесь, не работают, я использую стандартный терминал из Ubuntu 14.04. Как я могу настроить это?
JorgeeFG

@JorgeeFG: Я думаю, что это работало для меня из коробки gnome-terminalв Ubuntu 14.04, прежде чем я переключился на KDE. Соответствующая опция находится в настройках вашего терминала, esc-prefix vs high-bit и, возможно, некоторых других настройках. Некоторые из них не работают идеально для меня через SSH. (например, ctrl влево / вправо изменяет управляющий код для клавиши со стрелкой, и я 5Dбуквально появляюсь)
Питер Кордес

7

Добавьте следующие строки в ваш ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

Это похоже на ответ egmont, но вместо использования Page Up и Page Down он использует escape-последовательности для Arrow Up и Arrow Down. Этот способ намного удобнее использовать на Mac.


4

Я всегда склонен конфигурировать свои машины с большим значением HISTSIZE, чтобы он содержал более длинный список истории, а также HISTTIMEFORMAT со значением метки времени, чтобы я мог видеть, когда была выполнена команда.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "

3

Средства, которые я обычно использую, - это объединить historyкоманду сgrep

IE:

history | grep <command im looking for>

Это отобразит нумерованную историю команд, которые вы ввели, которые содержат эту команду, затем вы можете использовать:

!<number listed in history command>

повторить эту команду.

IE:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

с последующим: !571

повторю history | grep history


1
CR = намного лучше + намного безопаснее
PSkocik

1
Возможно, лично я нахожу историю, переданную grep, как более быстрый способ найти большинство команд. Насколько безопаснее, я не уверен, что вы имеете в виду, каковы риски при использовании истории в сравнении с поиском в ней с помощью cR?
Соус

2
@Gravy Я подозреваю, PSkocik означает, что !замена истории менее безопасна.
Дероберт

3
@Gravy Присущие риски будут случайно получить неправильную линию. Понятия не имею, почему ваш терминал завис, если только вы не использовали Control-S и не включили управление потоком xon / xoff (часто по умолчанию). Если это так, Control-Q вернет его.
Дероберт

1
Я согласен с @PSkocik, cr намного лучше, потому что проще редактировать строку истории, чем просто запускать ее снова тем же способом. Повторное выполнение одной и той же команды является тривиальным случаем того, что вы можете сделать, чтобы сэкономить время, набирая варианты на сложных однострочниках или завершая ввод в другой файл по длинному пути. Смотри мой ответ.
Питер Кордес

1

Я ежедневно использовал 4 подсказки (и некоторые другие) в своем терминале bash:

  • Выполнить последнюю команду: !!

  • Выполнить команду N из истории: !N

  • Вывести последнюю команду, начиная с префикса из истории: !prefix:p

  • Выполнить последнюю команду, начиная с префикса из истории: !prefix


1

Если вы можете использовать zshвместо bashвас cona, используйте для этого oh-my-zsh .

Он содержит стрелку вверх вниз по истории вашей команды. Это позволяет также ту же навигацию, когда вы уже набрали текст (как Mathlab).

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

https://github.com/robbyrussell/oh-my-zsh


1
oh-my-zshсодержит тонны вещей. Вы могли бы также сказать: эта точная функция включена в этот дистрибутив, когда все, что вам нужно, это конкретный параметр или приложение.
Муру

Я отредактировал пост: я предупредил, что это больше, чем простое приложение.
user9869932 24.09.15

1

Добавьте следующий псевдоним в ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Использование: h fireполучите список команд, содержащих огонь . или h ^fireполучите список команд, начинающихся с огня .

Это полезно, когда я хочу просматривать серию команд одновременно.

Кстати, '"'"'некрасиво, но я не смог найти других способов избежать одиночных кавычек в одинарных кавычках.


к вашему сведению - h="history | awk '{\$1=\"\"; print}'должно работать. альтернативно создайте функцию и вызовите ее.
DarkHeart

спасибо DarkHeart, но я попробовал твой код, но в моей среде он не работает, может быть, у меня что-то другое
Hosi Golden
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.