Як скасувати зміни в історії команд?


12

У системах UNIX ви можете натискати стрілки вгорі та внизу для навігації по попереднім командам. Це надзвичайно зручно.

Іноді я піднімаюсь вгору і знаходжу команду, яку хочу знову використовувати, але з деякими варіаціями. Якщо я ввожу такі зміни, у мене немає способу повернути початкову команду, якщо я не зареєстрував її history.

Чи є спосіб "скасувати" зміни команди в історії, доступ до якої здійснюється за допомогою клавіш?

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

Приклад

Я набрав такі "50 команд тому":

ls -l /etc/httpd/conf/

Тепер я підійшов до цієї лінії і змінив її на

ls -l /etc/init.d/

але не натиснув Enter. Тепер я хочу знову дійти ls -l /etc/httpd/conf/.

Моє оточення

$ echo $SHELL
/bin/bash
$ echo $TERM
xterm

Змінення історії команд, ймовірно, є (неправильним) ознакою оболонки, яку ви використовуєте. В ksh, наприклад, ви можете редагувати записи історії і посилатися на них , але залишити «попередню версію» записи; у вас є всі доступні команди.
Яніс

Під "це змінюється" я маю на увазі, що: з огляду на попередню команду, яку я змінив, досягнувши її стрілками, якщо я рухаюся стрілками вгору і вниз, стара команда не показуватиме так, як це було, але те, як я змінив це. Звичайно, якщо я введіть "enter", виконуючи команду, ця стара команда буде такою, якою вона була спочатку; але саме цього я намагаюся уникати і шукаю спосіб «скинути» команду до її початкового значення.
fedorqui

1
Також у цьому випадку kshповедінка тут відрізняється, схоже. А параметри редагування історії також залежать від обраного режиму редагування. У ksh«и ві-режимі, наприклад, старий запис не буде перезаписано, і я також може видати команду скасування, як в vi, з" та ".
Janis

Гм, це звучить дуже перспективно. Зараз я працюю в Баші і наразі не збираюся змінюватись ksh, але добре знати, що таке існує там.
fedorqui

Я хотів би знати, де 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

Ось ось кілька варіантів, щоб уберегти вас від прокрутки назад по всіх попередніх командах для читання.

Якщо ви пам'ятаєте якусь команду , натисніть ctrl+r і введіть те, що вам запам’яталося, щоб здійснити пошук за попередніми командами, що містять цей рядок. Якщо знову натиснути ctrl+ r, відобразиться наступний останній пошук, який проходить назад.

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

Команда fcbash вбудована корисна для перерахування номерів індексу поряд з попередніми командами readline.

fc -l -100 відобразить попередні 100 команд у рядку читання.

Крім того, якщо ОП знає, він шукає попередній 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 скасовує.


Це приємно, велике спасибі за детальну інформацію. Я приймаю відповідь Гілла, оскільки він робить саме те, що я шукаю, тоді як тут ви припускаєте, що я знаю багато речей про команду, яку я хочу повторити, що не завжди так.
fedorqui

Так, я згоден. Було б чудово, якби ця функція скасування була розширена, щоб я якось вводив команди.
Ійрін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.