Pamiętaj o wpisaniu na wpół wpisanego polecenia podczas sprawdzania czegoś

97

Często znajduję się w następującej pozycji: zacząłem pisać długie polecenie po znaku zachęty, ale w połowie dowiaduję się, że muszę sprawdzić coś za pomocą innego polecenia. Jest to problem, gdy jestem przy konsoli (bez X), co często się zdarza, ponieważ wtedy mam tylko następujące niezadowalające sposoby, o których wiem:

  • Naciśnij ctrl+ alt+ F2i zaloguj się na kolejnej wirtualnej konsoli i dowiedz się, czego chciałem, a następnie wróć i kontynuuj
  • ctrl+ a, wpisz echo + space+ enter, dowiedz się, co chciałem, naciskaj, aż znajdę polecenie, ctrl+ a, delx 5, ctrl+ ei kontynuuj
  • Podświetl to, co do tej pory wpisałem za pomocą myszy (jeśli działa gpm, co zwykle jest), naciśnij ctrl+, caby przerwać, dowiedz się, czego chciałem, uważając, aby nie używać myszy do wyróżnienia rzeczy, a następnie naciśnij środkowy przycisk myszy po nowej zachęcie i kontynuuj
  • Módlcie się do bogów wiersza poleceń, aby na wpół napisane polecenie nie przyniosło żadnych negatywnych skutków, ale po prostu nie powiodło się, i ostrożnie naciśnij Enter, a następnie dowiedz się, czego chciałem, naciśnij w górę, aż odzyskam polecenie i kontynuuj
  • Wskocz do mojej wehikułu czasu, cofnij się w czasie i przypomnij sobie, aby uruchomić ekran przed rozpoczęciem wpisywania polecenia, wróć do teraźniejszości, naciśnij ctrl+ a c, dowiedz się, czego chciałem, naciśnij ctrl+ a ctrl+ai kontynuuj

Chcę więc wiedzieć, czy jest jakiś bardziej elegancki sposób na zrobienie tego? Coś w rodzaju polecenia podpowłoki lub podobnego?

Najbardziej interesują mnie metody, które nie wymagają żadnych przygotowań ani konfiguracji do pracy.

Lauritz V. Thaulow
źródło

Odpowiedzi:

68

Nieco szybsza wersja Alexa Ctrl + A Ctrl+ K(który przesuwa się do przodu kolejki, a następnie wycina wszystko do przodu) jest po prostu użyć Ctrl+ U, która przecina tyłu na bash, a cała linia (niezależnie od aktualnej pozycji) na zsh. Następnie użyj Ctrl+, Yaby wkleić go ponownie

Michał Mrożek
źródło
1
Testując to, dochodzę do wniosku, że Ctrl + U nie przesuwa się do tyłu i nie przesuwa się do przodu, ale raczej przesuwa się do tyłu. Kursor w środku polecenia pozostawia wszystko, co znajduje się za nim w wierszu polecenia. Nadal 33% poprawa w stosunku do rozwiązania @ alex, ponieważ oszczędza to naciśnięcie klawisza.
Lauritz V. Thaulow,
2
@lazyr Oh, całkiem słusznie; na zshto nie wyciąć całą linię, ale na bashto kawałki do tyłu. Nigdy wcześniej nie zauważyłem tej różnicy
Michał Mrożek
2
Och, nie wiedziałem, że Ctrl + U umieszcza również tekst w celu zabicia bufora. Dobrze wiedzieć! :)
alex
1
^U ^Kbędzie miał taki sam efekt jak, ^A ^Kale jest nieco bardziej ergonomiczny i znacznie wygodniejszy pod screen.
intuicyjnie,
53

Wykonaj ctrl-A, aby dostać się do początku wiersza, przygotuj skrót i wciśnij Return - w ten sposób pozostanie on w historii poleceń jako komentarz i możesz wrócić do niego z kursorem w górę

EDYCJA: właśnie zauważyłem, że jest to nieco bardziej elegancki wariant na twoim # 2;)

jamespo
źródło
1
Tak i dlaczego o tym nie pomyślałem? Dziękuję Ci!
Lauritz V. Thaulow,
1
Muszę przeczytać, zanim opublikuję własną odpowiedź. James ma rację.
Sean C.
4
Zauważ, że to nie zadziała cshlub zshponieważ nie pozwalają na komentarze w interaktywnej powłoce. W zshtrzeba włączyć odpowiednią opcję: setopt interactive_comments.
sam hocevar,
1
@Sam Tak, ale „: polecenie” ma ten sam efekt („:” = polecenie zerowe)
barrycarter
6
@barrycarter: nie, :należy uważać za szkodliwe w tym celu i nigdy, nigdy nie będzie sugerowane. Wykona wszystko po średniku, wewnątrz backsku itp. Ze wszystkimi powiązanymi efektami ubocznymi.
sam hocevar,
29

Naciśnij Ctrl+A, Ctrl+Kaby przejść na początek linii i usunąć (zabić) na jej końcu. Następnie przeprowadź badania, a gdy będziesz gotowy, aby kontynuować, uderz Ctrl+Y(szarpnij), aby przywrócić linię (zabitą).

alex
źródło
3
Ach, teraz to bardziej przypomina to, co miałem na myśli. I robię to cały czas w Emacsie, powinienem pomyśleć o zrobieniu tego samego w wierszu poleceń.
Lauritz V. Thaulow,
13

W zsh wpisuję Ctrl+, Zaby „zawiesić” polecenie, które wpisuję, i wpisuję inne polecenie. Po uruchomieniu tego polecenia (lub przerwaniu go za pomocą Ctrl+ C) zawieszone polecenie wraca do edycji (nawet zapamiętuje pozycję kursora). Jako dodatkową wygodę, jeśli wiersz polecenia jest pusty, gdy wpisuję Ctrl+ Z, klawisz wywołuje bgwbudowane (zamiast tego podwójne Ctrl+ Zwysyła uruchomione polecenie bezpośrednio w tło).

fancy-ctrl-z () {
  emulate -LR zsh
  if [[ $#BUFFER -eq 0 ]]; then
    bg
    zle redisplay
  else
    zle push-input
  fi
}
zle -N fancy-ctrl-z
bindkey '^Z'          fancy-ctrl-z

Nie wiem jak zrobić coś podobnego w bashu.

W dowolnej powłoce możesz użyć mało zaawansowanej metody dodawania znaku #na początku bieżącej linii .

Gilles
źródło
2
Twoja funkcja jest godna podziwu, ale czy wiesz, że zshma ona już wbudowaną funkcję ? To się nazywa push-linei wystarczy, bindkeyaby się do niego dostać.
Caleb
@Caleb: Nie wiem, dlaczego używam, push-inputa nie push-linetutaj, push-linewydaje się bardziej odpowiednie (może tylko stare wersje zsh miały push-input?). Ale to nie zastępuje reszty funkcji.
Gilles
O ile wiem, jedyną różnicą jest taki sam efekt wiązania w tle z uruchomionym zadaniem. Czy coś brakuje?
Caleb
1
@Caleb: Nie, po prostu uważam, że kombinacja obu jest wygodna ( push-linejest bezużyteczna na pustej linii, bgwłączenie Ctrl+Zjest użyteczne tylko wtedy, gdy właśnie zawiesiłem ten proces Ctrl+Z) i mnemoniczne (albo używam procesu w tle lub częściowy wiersz poleceń).
Gilles,
3
@Caleb push-inputzawiesza cały bufor wejściowy, podczas gdy push-linezawiesza tylko bieżącą linię. Jeśli piszę polecenie wieloliniowe, chcę zawiesić całe polecenie, więc push-inputjest to właściwe. Uważam, że jest to push-inputbardziej przydatne niż push-line(jeśli chcę opóźnić linię w wielowierszowym buforze wejściowym, mogę po prostu przejść do początku linii i wstawić nową linię), więc w rzeczywistości zastanawiam się, dlaczego push-linedostałem domyślne przypisanie klawiszy, a nie push-input.
Gilles
13

W bash po prostu wpisz Alt+ #.

Następnie, gdy będziesz gotowy, naciśnij, Upa następnie Alt+ #.

Pierwszy umieszcza #na początku wiersza, aby zamienić go w komentarz, a następnie akceptuje wiersz, tak jakbyś nacisnął Enter.

Następnie, gdy zrobisz to po raz drugi, zobaczy, że linia ma już #na początku znak , więc usuwa go i akceptuje, ponownie oszczędzając Enterklucz.

Jeśli po raz drugi wstawisz inny #, musisz zamiast tego wpisać Alt+ - Alt+ #.

Możesz sprawić, że zsh zrobi to samo, wstawiając

bindkey -M emacs '\e#' pound-insert

w twoim ~ / .zshrc.

Lub, jeśli używasz powiązań vi, możesz pisać #z trybu poleceń zarówno w bash, jak i zsh.

Mikel
źródło
2
Nie działa dla mnie, drugie polecenie miało na celu usunięcie # po prostu dodaje więcej # z przodu.
Lauritz V. Thaulow,
1
Czy pierwszy działa? Jakiej wersji bash używasz?
Mikel
3
Alt + # działa tak, jak opisano w trzecim akapicie, ale nie tak jak w czwartym, po prostu wstawia kolejny # na przód i akceptuje wiersz. Używam wersji bash 4.1.5 (1) na Ubuntu 10.10.
Lauritz V. Thaulow,
1
Och, kochanie, w bash wymaga to argumentu numerycznego, np. Esc+1Następnie Alt+, #aby przełączyć.
Mikel,
To działa, ale jest o wiele bardziej kłopotliwe niż tylko Ctrl + A Del Ctrl + E, szczególnie na moim układzie klawiatury, gdzie Alt + # to tak naprawdę Alt + Shift + 3.
Lauritz V. Thaulow,
10

Jedną z moich ulubionych funkcji zshjest wbudowana funkcja push-line, która zajmuje się tym bez żadnego włamania w innych odpowiedziach tutaj. Mam związany z Ctrl+ lw moim .zshrcpliku w następujący sposób:

bindkey '^L' push-line

Następnie, gdy piszę jakieś polecenie i muszę zrobić coś naprawdę szybko, mogę je wywołać za pomocą jednego klawisza i wyświetlić pusty monit. Po uruchomieniu drugiego polecenia monit jest automatycznie wypełniany tym, co pisałem wcześniej.

Możesz nawet połączyć wiele warstw tego, a polecenia wrócą do ciebie w odwrotnej kolejności, aby wypchnąć je do kolejki.

Caleb
źródło
5
Domyślnie powiązane Ctrl+Qi ESC q(w trybie emacsa).
Gilles,
Czy istnieje coś podobnego do bash?
Magnus
@Magnus: Przejrzyj pozostałe odpowiedzi na to pytanie. Istnieją rozwiązania do bashu, po prostu nie tak eleganckie jak to.
Caleb
@Caleb, powinienem był być bardziej szczegółowy, czy istnieje podobna kombinacja jednego klawisza do bash?
Magnus
1
To jest oczywiście „poprawna” odpowiedź, dla Zsh w każdym razie! Chcę tylko wspomnieć o push-line-or-editwidżecie, który domyślnie nie jest powiązany z żadną mapą klawiszy. W wierszu najwyższego poziomu robi to samo push-line, ale na każdym niższym poziomie wiersza przekształca całe wprowadzone polecenie w bufor wieloliniowy. Dwie świetne funkcje w jednym skrócie klawiszowym! Mogę polecić oprawa push-line-or-editzamiast zwykłego push-line. Nic nie tracisz i zyskujesz użyteczną funkcjonalność.
wjv,
5

Oprócz sztuczki ctrl- a ctrl- kjeśli jesteś na ekranie, po prostu ctrl- a daby odłączyć, a następnie ponownie podłączscreen -r

Możesz także po prostu otworzyć kolejne okno za pomocą ctrl+a c

królikarnia
źródło
8
Jeśli jesteś na ekranie, po prostu otwórz kolejne okno za pomocą Ctrl+A c.
Gilles,
1
@Gilles .. chyba że musisz użyć jakiegoś aspektu stanu powłoki (zmienne, funkcje, aliasy itp.).
intuicyjnie,
4

Alternatywny sposób, choć nie doskonały, naciśnij Ctrl-X Ctrl-E. Spowoduje to otwarcie domyślnego edytora zawierającego polecenie wpisane do połowy. Następnie możesz zapisać polecenie w pliku lub otworzyć nową powłokę z poziomu edytora. Gdy wyjdziesz z nowej powłoki, powróci ona do edytora, a zapisanie zawartości spowoduje jej automatyczne wykonanie.

Nie jest to idealne, ponieważ nie przywraca oryginalnej powłoki, ale albo wymusza wykonanie polecenia, albo całkowicie je odrzuca. Ale nie ma tymczasowych wyborów ani buforów zabijania, o które należy się martwić, a także kilka fajnych poprawek, np. If editor = vi

:wq            # execute the command
:cq            # cancel and abort
:! command     # execute command
:shell         # open a new shell
:r filename    # insert the contents of a file for editing
:r ! command   # insert the output of a command for editing
forcefsck
źródło
Bardzo miła alternatywa. Jestem vi-emacs-agnostic, więc będę szczęśliwy jako małż, używając tego, gdy powertools są naprawdę potrzebne. (Mówiąc o vi, próbowałem jakiś czas temu emulator linuksa N64 Mupen64Plus. Esc wychodzi z emulatora bez zapisywania. Wkrótce zrezygnowałem z grania.)
Lauritz V. Thaulow
1
@lazyr, dla uruchomienia debian / ubuntu sudo update-alternatives --config editori wybierz swój ulubiony edytor. W przypadku innych systemów ustaw zmienne środowiskowe EDITOR lub VISUAL na ulubiony edytor, np. Dodaj export EDITOR=/usr/bin/nano.bashrc.
forcefsck,
3

Podobnie do metody dodawania #na początku wiersza, istnieje prawdopodobnie łatwiejsza metoda, której używam, która nie wymaga powrotu na początek wiersza:

Po prostu dodaj otwartą wycenę i nie zamykaj jej, ani pojedynczej, ani podwójnej.

Następnie naciśnij Enter.

Następnie naciśnij CtrlC.

Polecenie częściowe jest zapisywane w historii poleceń (dostępne za pomocą strzałki w górę), ale w rzeczywistości nie jest wykonywane.

Dzika karta
źródło
2

Używając zsh, jeśli wpiszesz <ESC> q(klawisz Escape, a następnie Q), wiersz polecenia zostanie wycięty, aby można było wpisać inne polecenie. Automatycznie otrzymasz wycięty tekst w następnym monicie.

Może zapamiętać kilka linii jednocześnie, więc możesz z niego korzystać, gdy linia czeka na Ciebie. Możesz nawet użyć go na pustej linii, aby opóźnić wznowienie linii cięcia.

To nie jest najbardziej efektywny sposób, jeśli musisz użyć kilku poleceń do sprawdzenia / przygotowania (będziesz musiał ponownie wpisać <ESC> qprzed każdym poleceniem). Ale myślę, że można powiązać go z krótszym skrótem.


Jeśli chcesz tylko sprawdzić instrukcję, wpisz <ESC> h(klawisz Escape, a następnie H). To uruchomi run-helpwbudowane, z pierwszym słowem wiersza poleceń jako argumentem. Po zakończeniu znajdziesz nienaruszoną linię.

loxaxs
źródło
Większość terminali pozwoli ci M-qzamiast tego<ESC> q
sleblanc