Jak szybko uzyskać poprzednie wyjście liniowe w terminalu bez użycia myszy?

13

Terminal Linux (np. Ubuntu), czy istnieje metoda uzyskania ostatniej linii? Powiedzmy, że losowo wpisuję tdpolecenie, które nie zostało zainstalowane w moim systemie, więc otrzymam komunikat podobny do poniższego. Chciałbym mieć „skrót” do sudo apt-get install textdrawszybkiego uruchamiania .

Czy istnieje takie narzędzie lub jak mogę skopiować ostatni wiersz do schowka bez użycia myszy?

username@WorkStation:~$ td
The program 'td' is currently not installed. You can install it by typing:
sudo apt-get install textdraw
username@WorkStation:~$
Daniel
źródło
Naciśnij strzałkę w górę? Próbowałeś tego? Sprawdź także polecenie historii w Linuksie, które również może Ci pomóc.
Richie086,
Terminalowe programy multipleksujące, tmux i screen, zapewniają możliwość wprowadzania tekstu do schowka. Jednak domyślny interfejs GUI Ubuntu może być łatwiejszy, więc podejrzewam, że może być dostępna łatwiejsza odpowiedź. Naciśnięcie PgUp, Shift-PgUp lub Ctrl-PgUp może umożliwić przewijanie.
TOOGAM
3
@ Richie086 Należy pamiętać, że to, co jest mi potrzebne sudo apt-get install textdraw, nie td. strzałka w górę da mi tylkotd
Daniel

Odpowiedzi:

6

Jeśli nie przeszkadza ci trochę nieprzyzwoitości (ja nie), możesz chcieć skorzystać z kurwa , narzędzia, które robi dokładnie to, o co prosiłeś.

Nie do końca, ale rozwiązuje ten sam problem. Zamiast pobrać najnowszą linię, próbuje dopasować ostatnie wpisane polecenie.

Kurwa próbuje dopasować regułę do poprzedniego polecenia, tworzy nowe polecenie za pomocą dopasowanej reguły i uruchamia je.

Przykłady przedstawione w repozytorium pokazują kilka wspomnianych scenariuszy.

wprowadź opis zdjęcia tutaj

Alfa
źródło
2

Krótka odpowiedź: nie, prawdopodobnie nie masz dostępnej metody, aby to zrobić.

Długa odpowiedź:

  • gdy jest to możliwe , aby mieć emulator terminala, który pozwala na „tylko” read back zawartości ekranu i edytować je w praktyce, że nie odbywa się często z powodu obaw, że jakiś niechciany program mógłby Snoop na swoich danych wprowadzanych z klawiatury.
  • można zaprojektować powłokę, która przechwytuje dane wyjściowe poleceń i umożliwia ich edycję (podobnie jak historia poleceń). Byłoby to skomplikowane, gdyby polecenie było czymś podobnym vi(gdzie wynik nie jest ładnym tekstem zorientowanym liniowo). Bash i tak tego nie robi.

W praktyce ludzie robią, aby obejść to ograniczenie, używając innych programów do przechwytywania danych wyjściowych poleceń i ich edycji. Ale to nie rozwiąże twojego bezpośredniego problemu.

Na przykład używam vi-like-emacs do wydawania poleceń powłoki ad hoc. Jeśli nie wymagają one dalszych danych wejściowych, dobrze jest uruchomić je w oknie , przechwytując dane wyjściowe polecenia - i edytując dane wyjściowe w razie potrzeby w celu udoskonalenia polecenia. Emacs pozwala także na zrobienie czegoś takiego, a także na vim.

Thomas Dickey
źródło
2

Jeśli dostałeś ten komunikat w Ubuntu po uruchomieniu nieistniejącej komendy z bash, twój system prawdopodobnie używa command_not_found_handlefunkcji. Możesz to zobaczyć w /etc/bash.bashrc.

Może być trywialne hakowanie: Właśnie utworzyłem skrypt o nazwie cnfh:

#!/bin/bash

# if the command-not-found package is installed, use it
if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then
        function command_not_found_handle {
                # check because c-n-f could've been removed in the meantime
                if [ -x /usr/lib/command-not-found ]; then
                   /usr/lib/command-not-found -- "$1"
                   return $?
                elif [ -x /usr/share/command-not-found/command-not-found ]; then
                   /usr/share/command-not-found/command-not-found -- "$1"
                   return $?
                else
                   printf "%s: command not found\n" "$1" >&2
                   return 127
                fi
        }
fi


"$@"
RET_VAL=$?
if [ $RET_VAL -eq 127 ]; then
  OUT=$(command_not_found_handle "$@" 2>&1)
  $(echo $OUT |sed -n 's/.*\(apt-get install .\+\)$/\1/p')
fi

Następnie uruchom polecenie td za pomocą tego skryptu:

# ./cnfh td

Korzystanie z Ubuntu 14.04.2 LTS . Mam nadzieję że to pomogło.

Kadir
źródło
To wygląda naprawdę fajnie i może coś, co chciałbym dodać do mojego systemu. Czy możesz dodać informacje o tym, jak to działa? Wbudowany kod do obsługi uzupełnień i podobnych rzeczy jest dość trudny do zrozumienia.
Joe
2

W tmux v2.4 i nowszych (od tego momentu https://github.com/tmux/tmux/commit/76d6d3641f271be1756e41494960d96714e7ee58 ) z send-keys -X. Może to być możliwe w starszych wersjach, z inną składnią.

W .tmux.conf:

bind ! copy-mode \;\
       send-keys -X cursor-up \;\
       send-keys -X select-line \;\
       send-keys -X cursor-left \;\
       send-keys -X copy-selection-and-cancel \;\
       paste-buffer

Teraz prefix+!skopiuje ostatni wiersz w bieżącej pozycji kursora.

cursor-left można pominąć, jeśli chcesz wykonać go bezpośrednio bez wpisywania return.

Uwaga : nie będzie działać, jeśli ostatni wiersz jest pusty lub jeśli jest zawinięty, ale nadal jest przydatny w większości przypadków

lbonn
źródło
1

Aby wykonać ostatni wiersz wyniku ostatniego polecenia, jeśli chcesz ponownie wykonać to polecenie (ponieważ nie wykonało ono nic oprócz wydania komunikatu diagnostycznego), wykonaj

$($(fc -ln -1) | tail -n 1)

Krok po kroku (warstwa po warstwie):

  • fc (co może oznaczać „Napraw polecenie”) to wbudowane polecenie powłoki umożliwiające dostęp do historii poleceń.

    • -ln
      • l(małe litery L) - l Zestawienie poprzednie polecenie (S)
      • n- nie obejmuje polecenia n Umbry
    • 1 (jeden) - odnosi się do najnowszego polecenia

    fc -ln -1 wyświetla najnowsze polecenie, bez numeru polecenia.

  • $(fc -ln -1) wykonuje ostatnie polecenie.
  • $(fc -ln -1) | tail -n 1wykonuje ostatnie polecenie i wyświetla ostatni wiersz wyniku. To jest sudo apt-get install textdrawlinia w twoim przykładzie.
  • $($(fc -ln -1) | tail -n 1)wykonuje to polecenie.

Możesz to zmienić na:

alias execute_last_line_of_output_from_previous_command='$($(fc -ln -1) | tail -n 1)'

Wybieram krótszą nazwę dla aliasu.

Uwagi:

  • Działa to tylko dla prostych poleceń - bez znaków specjalnych, takich jak |, <, >, ;, &, a nawet cytaty. Jeśli potrzebujesz obsługiwać złożone polecenia, prawdopodobnie możesz to zrobić, dodając eval, ale nie jest to zalecane.
  • Jeśli potrzebujesz dostępu do czegoś innego niż ostatni wiersz wyniku (np. Od siedemnastego do ostatniego ostatniego wiersza), możesz zrobić coś wiersza tail -n 17 | head -n 1.
  • Jeśli potrzebujesz dostępu do czegoś innego niż ostatnie polecenie, możesz zmienić argumenty na fc. Zauważ, że fc -ln -1to skrót fc -ln -1 -1. Aby pobrać trzecie ostatnie polecenie, użyj fc -ln -3 -3.
  • Jeśli potrzebujesz elastyczności takiej jak powyżej, powinieneś prawdopodobnie napisać funkcję powłoki, która przyjmuje argumenty, a nie alias.
G-Man mówi „Przywróć Monikę”
źródło