Jak cofnąć zmiany w historii poleceń?

12

W systemach UNIX możesz naciskać górne i dolne strzałki, aby poruszać się po poprzednich poleceniach. Jest to bardzo przydatne.

Czasami wchodzę na górę i znajduję polecenie, którego chcę użyć ponownie, ale z pewnymi zmianami. Jeśli dokonam takich zmian, nie będę mógł odzyskać oryginalnej komendy, chyba że ją sprawdzę history.

Czy istnieje sposób „cofnięcia” zmian polecenia w historii, do której dostęp uzyskuje się za pomocą klawiszy?

Moje obecne obejście polega na dodaniu #polecenia a do polecenia. W ten sposób bieżące polecenie jest wykonywane jako komentarz, więc nic się nie dzieje. Następnie mogę ponownie przeglądać polecenia za pomocą klawiszy. Problem polega na tym, że polecenie, którego użyłem, może być bardzo odległe na liście, więc wznowienie gry dwieście razy to trochę. Control + R też nie jest rozwiązaniem, ponieważ mogę nie pamiętać dokładnie tego, czego szukałem.

Przykład

Wpisałem następujące „50 poleceń temu”:

ls -l /etc/httpd/conf/

Teraz podszedłem do tej linii i zmieniłem ją na

ls -l /etc/init.d/

ale nie nacisnął Enter. Teraz chcę przejść do tego ls -l /etc/httpd/conf/ponownie.

Moje środowisko

$ echo $SHELL
/bin/bash
$ echo $TERM
xterm
fedorqui
źródło
Zmiana historii poleceń jest prawdopodobnie (błędną) funkcją używanej powłoki. Na kshprzykład możesz edytować wpisy historii i wywoływać je bez usuwania „poprzedniej wersji” wpisu; masz wszystkie wywołane polecenia dostępne.
Janis
Przez „zmienia się” mam na myśli, że: biorąc pod uwagę poprzednie polecenie, które zmieniłem po osiągnięciu go za pomocą strzałek, jeśli przechodzę w górę i w dół ze strzałkami, stare polecenie nie będzie pokazywało, jak było, ale sposób, w jaki zmodyfikowałem to. Oczywiście, jeśli wpiszesz „enter” wykonując polecenie, to stare polecenie będzie takie, jakie było na początku; ale właśnie tego staram się unikać i szukam sposobu na „zresetowanie” polecenia do jego początkowej wartości.
fedorqui
1
kshWygląda na to, że również w tym przypadku zachowanie się tu różni. A opcje edycji historii zależą również od wybranego trybu edycji. Na kshprzykład w trybie vi stary wpis nie jest nadpisywany, a także mogę wydać polecenie cofnięcia, podobnie jak w vi, za pomocą „u”.
Janis
Uhm, to brzmi bardzo obiecująco. Pracuję teraz w Bash i obecnie nie zastanawiam się nad zmianą ksh, ale dobrze wiedzieć, że coś takiego istnieje.
fedorqui
Chciałbym wiedzieć, gdzie bash przechowuje historię ostatnich poleceń przed zapisaniem do pliku historii, gdy powłoka jest zamknięta. Może to pomóc w ustaleniu, czy jest to możliwe. Ktoś? Myślałem, że może to być jedna ze zmiennych powłoki, ale nie mam teraz czasu na zastanawianie się nad instrukcją.
iyrin

Odpowiedzi:

10

Tak długo, jak edytowałeś pozycję historii, ale Enterjeszcze nie nacisnąłeś , aby wrócić do pierwotnej pozycji, kilkakrotnie naciśnij Ctrl+ _- undopolecenie - aż nie spowoduje to dalszych zmian. Wróciłeś do pierwotnego wpisu.

Gilles „SO- przestań być zły”
źródło
5

Powróć do pierwotnego polecenia po wprowadzeniu wielu zmian w wierszu:

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.

Mjest meta-kluczem, który jest altrdla mnie.


Darmowe, ale pomocne informacje

Kiedy już wykonana komenda OP jak wcześniej zrobił (zdarza się), nie ma nic do „Cofnij”, ponieważ polecenia są obsługiwane i zapamiętanego przez GNU readline biblioteki i nie jest napisane do$HISTFILE momentu wyjścia powłoki. Powodem, dla którego o tym wspominam, jest to, że nie można po prostu greptego $HISTFILEoczekiwać, a wyjście z powłoki może nie być idealne.

Oto kilka opcji, które pozwolą Ci uniknąć przewijania wszystkich poprzednich poleceń readline.

Jeśli pamiętasz niektóre polecenia , naciśnij ctrl+ ri wpisz, co pamiętasz, aby przeszukać poprzednie polecenia zawierające ten ciąg. Ponowne naciśnięcie ctrl+ rspowoduje wyświetlenie następnego najnowszego, wyszukiwania do tyłu.

Na przykład wpisz ls -lnastępnie ctrl+ rtyle razy, ile potrzeba, aby znaleźć poprzednie polecenie, którego szukasz. Jeśli przejdziesz obok tego, ctrl+ sprzeszuka do przodu od bieżącej pozycji.

fcBash wbudowane polecenia jest pomocne notować numery indeksów obok poprzednich poleceń readline.

fc -l -100 wyświetli listę 100 poprzednich poleceń w trybie readline.

Dodatkowo, jeśli OP wie, że szuka poprzedniego ls -lpolecenia, może przesłać dane wyjściowe do grep:fc -l -100 | grep 'ls -l'

Powinno to spowodować wyświetlenie listy poprzednich ls -lpoleceń poprzedzonych numerem indeksu. Dane wyjściowe wyglądają następująco:
2065 ls -l

Teraz możesz użyć oznaczenia zdarzenia, w !nktórym nznajduje się numer indeksu. W tym przykładzie wykonywanie !2065zostanie rozwinięte do ls -l.


Chociaż po tym nie pomaga, każdy, kto chce zachować najnowszą historię poleceń podczas modyfikowania poprzednich poleceń, powinien zapoznać się z HISTORY EXPANSIONsekcją man bash. Oto kilka alternatywnych metod modyfikowania starych poleceń bez nadpisywania historii.

W tej Event Designatorssekcji pokazano, jak łatwo edytować ciąg znaków za pomocą ostatnio używanego polecenia.

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

Przykład:

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

Najnowsze polecenia będą teraz wyświetlać:

echo foo
echo bar

W powyższym przykładzie wyjaśniono również, jak używać sedzamieniać ciąg w desygnatorze zdarzenia.

!-n    Refer to the current command minus n.

Jeśli więc w historii echo foopojawią się 3 polecenia , użyjesz:
!-3:s/foo/bar

Zwróć uwagę, że w tym przypadku oznaczenia zdarzeń pojawią się w Twojej historii po wykonaniu polecenia echo bar. Nie pojawi się w historii jako !-3:s/foo/bar.

Po prostu wyrzucam to, ponieważ wydaje się to ściśle powiązane, nawet jeśli jest to bardziej „nie rób” niż rozwiązanie „cofnij”, którego szuka OP.

iyrin
źródło
To miłe, wielkie dzięki za szczegółowe informacje. Przyjmuję odpowiedź Gillesa, ponieważ robi dokładnie to, czego szukam, podczas gdy tutaj zakładasz, że wiem wiele rzeczy na temat polecenia, które chcę powtórzyć, co nie zawsze jest prawdą.
fedorqui
Tak! Zgadzam się. Byłoby wspaniale, gdyby ta funkcja cofania została rozszerzona na wcześniej wprowadzone w jakiś sposób polecenia.
iyrin