Как отменить изменения в истории команд?

12

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

Иногда я поднимаюсь и нахожу команду, которую хочу использовать снова, но с некоторыми изменениями. Если я внесу такие изменения, у меня не будет способа вернуть исходную команду, если я не проверю ее history.

Есть ли способ «отменить» изменения команды в истории, доступ к которым осуществляется через ключи?

Мой текущий обходной путь - добавить #команду к команде. Таким образом, текущая команда выполняется как комментарий, поэтому ничего не происходит. Затем я могу снова просмотреть команды с помощью клавиш. Проблема в том, что команда, которую я использовал, может быть очень далеко в списке, поэтому двукратное повышение - немного. Control + R также не является решением, так как я не могу точно вспомнить, что я искал.

пример

Я набрал следующее "50 команд назад":

ls -l /etc/httpd/conf/

Теперь я поднялся на эту линию и изменил ее на

ls -l /etc/init.d/

но не нажал ввод. Теперь я хочу добраться до ls -l /etc/httpd/conf/снова.

Моя среда

$ echo $SHELL
/bin/bash
$ echo $TERM
xterm
fedorqui
источник
Изменение истории команд, вероятно, является (неправильной) особенностью используемой вами оболочки. В ksh, например, вы можете редактировать записи истории и ссылаться на них , не удаляя «предыдущую версию» записи; у вас есть все вызванные команды доступны.
Янис
Под «он меняется» я имею в виду: учитывая предыдущую команду, которую я изменил после достижения ее стрелками, если я поднимаюсь и опускаюсь стрелками, старая команда не будет показывать то, что было, но то, как я изменил Это. Конечно, если я наберу «enter», выполняя команду, эта старая команда будет такой, какой она была изначально; но это именно то, чего я пытаюсь избежать, и ищу способ «сбросить» команду до ее первоначального значения.
Федорки
1
Также в этом случае kshповедение здесь отличается. И ваши параметры редактирования истории также зависят от выбранного режима редактирования. В ksh«ы ви-режиме, например, старая запись не перезаписывается, и я также может выдать команду отмены, как в vi, с„и“.
Янис
Хм, это звучит очень многообещающе. Я сейчас работаю в Bash и в настоящее время не собираюсь переходить на ksh, но приятно знать, что такая вещь существует там.
Федорки
Я хотел бы знать, где bash хранит недавнюю историю команд, прежде чем записывать в файл истории, когда оболочка закрыта. Это может помочь определить, возможно ли это. Кто - нибудь? Я подумал, что это может быть одна из переменных оболочки, но сейчас у меня нет времени изучать руководство.
Айрин

Ответы:

10

Если вы отредактировали запись истории, но еще не нажали Enter, чтобы вернуться к исходной записи, несколько раз нажмите Ctrl+ _- undoкоманду - до тех пор, пока она не внесет никаких изменений. Вы вернулись к исходной записи.

Жиль "ТАК - перестань быть злым"
источник
5

Вернитесь к исходной команде, когда вы сделали несколько изменений в строке:

revert-line (M-r) 
    Undo all changes made to this line. This is like 
executing the undo command enough times to get back to the beginning.

Mэто мета ключ, который altrдля меня.


Бесплатная, но полезная информация

Когда вы уже выполнены команда , как OP было сделаны ранее (это бывает), нет ничего , чтобы «отменить» , поскольку команды обрабатываются и запоминаются GNU Readline библиотеки и не написанные$HISTFILE до выходов оболочки. Причина , почему я говорю об этом, потому что вы не можете просто , как можно было бы ожидать , и это не может быть идеальным для выхода из оболочки.grep$HISTFILE

Итак, вот несколько вариантов, чтобы уберечь вас от прокрутки всех предыдущих команд readline.

Если вы помните какую-либо команду , нажмите ctrl+ rи введите то, что вы помните, чтобы найти предыдущие команды, содержащие эту строку. Повторное нажатие ctrl+ rпокажет следующий самый последний поиск в обратном направлении.

Например, введите ls -lзатем ctrl+ rстолько раз, сколько потребуется , чтобы найти предыдущую команду , которую вы ищете. Если вы прокрутите мимо него, ctrl+ sбудет искать вперед с текущей позиции.

fcБаш встроенной команды полезен для отображения номера индексов наряду с предыдущими командами чтения строки.

fc -l -100 перечислит предыдущие 100 команд в readline.

Кроме того, если OP знает, что он ищет предыдущую ls -lкоманду, он может передать вывод, grepнапример:fc -l -100 | grep 'ls -l'

Это должно вывести список предыдущих ls -lкоманд, которым предшествует порядковый номер. Вывод выглядит так:
2065 ls -l

Теперь вы можете использовать указатель события, !nгде указывается nномер индекса. В этом примере выполнение !2065будет расширено до ls -l.


Хотя это не помогает после этого, любой, кто хочет сохранить историю последних команд при изменении предыдущих команд, должен увидеть HISTORY EXPANSIONраздел man bash. Вот несколько альтернативных способов изменения старых команд без перезаписи истории.

В Event Designatorsразделе показано, как вы можете легко редактировать строку из последней использованной команды.

^string1^string2^
              Quick  substitution.  Repeat the previous command, replacing string1 with string2.  Equivalent to
              ``!!:s/string1/string2/'' (see Modifiers below).

Пример:

$ echo foo
foo 
$ ^foo^bar
echo bar
bar

Самые последние команды теперь будут отображать:

echo foo
echo bar

Приведенный выше пример также объясняет, как использовать sedдля замены строки в указателе события.

!-n    Refer to the current command minus n.

Так что если в истории есть 3 команды, echo fooто вы должны использовать:
!-3:s/foo/bar

Обратите внимание, что в этом случае указатели событий появятся в вашей истории как выполненная команда echo bar. Это не появится в истории как !-3:s/foo/bar.

Просто добавьте это, поскольку это кажется тесно связанным, даже если это больше «не делай», чем «отменить» решение, которое ищет OP.

iyrin
источник
Это приятно, большое спасибо за подробную информацию. Я принимаю ответ Жиля, поскольку он делает именно то, что я ищу, тогда как здесь вы предполагаете, что я знаю много вещей о команде, которую я хочу повторить, что не всегда так.
Федорки
Да я согласен. Было бы здорово, если бы эта функция отмены была распространена на ранее введенные мной команды.
Айрин