Wiem, że mogę uruchomić ostatnie polecenie w bash !!
, ale jak mogę uruchomić ostatni wiersz wyniku?
Mam na myśli przypadek użycia tego wyjścia:
The program 'git' is currently not installed. You can install it by typing:
sudo apt-get install git
Ale nie wiem, jak mogę to uruchomić. Myślę o czymś takim !!
, może @@
lub podobnym?
command_not_found_handle
funkcji powłoki lub uruchamianego skryptu (zwykle po prostu/usr/lib/command-not-found
). Myślę, że możesz to zrobić, aby wyświetlać się interaktywnie z opcją automatycznego instalowania pakietu lub (prawdopodobnie lepiej), aby nazwa pakietu była gdzieś przechowywana i można ją zainstalować, uruchamiając krótkie polecenie. To wystarczająco różni się od tego, o co tutaj pytałeś, możesz rozważyć opublikowanie osobnego pytania na ten temat.Odpowiedzi:
Polecenie
$(!! |& tail -1)
powinno wykonać:Jak widać
sudo apt-get install git
polecenie jest uruchomione.EDYCJA: Rozkładanie
$(!! |& tail -1)
$()
jestbash
wzorcem zastępowania poleceńbash
rozwinie!!
się do ostatniego wykonanego polecenia|&
część jest trudna. Normalnie potok|
pobiera STDOUT polecenia po lewej stronie i przekazuje go jako STDIN do polecenia po prawej stronie|
, w twoim przypadku poprzednie polecenie wypisuje swoje wyjście na STDERR jako komunikat o błędzie. Tak więc robienie|
nie pomogłoby, musimy przekazać zarówno STDOUT, jak i STDERR (lub tylko STDERR) do polecenia po prawej stronie.|&
przekaże STDOUT i STDERR zarówno jako STDIN do polecenia po prawej stronie. Alternatywnie, lepiej możesz przekazać tylko STDERR:tail -1
jak zwykle wydrukuje ostatni wiersz z jego wejścia. Tutaj zamiast wypisywania ostatniego wiersza możesz być bardziej precyzyjny, jak wypisywanie wiersza zawierającegoapt-get install
polecenie:źródło
TL; DR:
alias @@='$($(fc -ln -1) |& tail -1)'
Funkcje interakcji historii Basha nie oferują żadnego mechanizmu do sprawdzania wyników poleceń. Powłoka tego nie przechowuje , a ekspansja historii dotyczy specjalnie poleceń, które sam wykonałeś, lub części tych poleceń.
Pozostawia to podejście polegające na ponownym uruchomieniu ostatniego polecenia i przekazaniu zarówno stdout, jak i stderr (
|&
) do podstawienia polecenia. Odpowiedź heemayla osiąga to, ale nie można jej użyć w aliasie, ponieważ powłoka wykonuje ekspansję historii przed rozwinięciem aliasów, a nie później.Nie mogę też sprawić, by rozszerzenie historii działało w funkcji powłoki, nawet poprzez włączenie go w funkcji za pomocą
set -H
. Podejrzewam,!!
że funkcja nigdy nie zostanie rozwinięta i nie jestem pewien, do czego by ją rozwinął, ale w tej chwili nie jestem pewien , dlaczego tak nie jest.Dlatego jeśli chcesz skonfigurować rzeczy tak, abyś mógł to zrobić przy bardzo małym pisaniu, powinieneś użyć
fc
wbudowanej powłoki zamiast rozszerzenia historii, aby wyodrębnić ostatnie polecenie z historii. Ma to tę dodatkową zaletę, że działa nawet po wyłączeniu rozszerzania historii.Jak pokazano w Gordon Davisson jest odpowiedzią na stworzenie aliasu zawierające interpretację historii bash (na Super User ),
$(fc -ln -1)
symuluje!!
. To z podłączeniem do!!
w dowodzenia heemayl za$(!! |& tail -1)
plony:Działa to podobnie,
$(!! |& tail -1)
ale można przejść do definicji aliasu:Po uruchomieniu tej definicji, włożeniu jej
.bash_aliases
lub.bashrc
uruchomieniu nowej powłoki, możesz po prostu wpisać@@
(lub jakkolwiek nazwałeś alias), aby spróbować wykonać ostatni wiersz danych wyjściowych z ostatniego polecenia.źródło
./script
, nie to, że źródło z.
lubsource
wbudowane - jestem pewien. Bash dołącza do pliku przy wyjściu z powłoki lub po uruchomieniuhistory
z-a
lub-w
(patrzhelp history
). Gdyby tak było, polecenia w wielu interaktywnych powłokach byłyby przeplatane (pojawiające się w kolejności ich uruchamiania). Możesz sprawić, że będzie się od razu dołączał. . Ale myślę, że jest jeszcze wiele do zrobienia, abyfc
pracować w skrypcie. Sugeruję opublikowanie nowego pytania na ten temat. Jeśli tak, prosimy o komentarz tutaj z linkiem do niego.Jeśli używasz emulatora terminala pod X, jak
gnome-terminal
,konsole
lubxterm
, można użyć zaznaczenia X na coś skopiować i wkleić:Użyj wyboru podstawowego
Wybierz całą linię, aby uruchomić trzykrotnie lewym przyciskiem myszy .
Następnie wklej go do wiersza poleceń za pomocą środkowego kliknięcia przycisku .
Powinno to działać w większości emulatorów terminali. Wykorzystuje podstawowy wybór, bez dotykania schowka - są one oddzielne.
Technicznie wybiera, a następnie łączy kopiowanie i wklejanie w jednej operacji.
źródło
Jak wspomniał Eliah Kagan , powłoka nie przechowuje danych wyjściowych polecenia. Istnieje jednak sposób na uzyskanie ostatniego wiersza wyjścia ostatniego polecenia bez ponownego uruchamiania polecenia , jeśli uruchomisz screen .
Umieść w tobie następujące linie
~/.screenrc
:Następnie możesz nacisnąć Ctrl+, ataby wstawić poprzednią linię do bieżącego monitu. Byłoby możliwe, aby to również automatycznie naciskało klawisz Enter, ale prawdopodobnie lepiej jest to sprawdzić przed uruchomieniem i po prostu nacisnąć klawisz Enter ręcznie.
Jak to działa:
register t
rejestruje ciąg znaków w buforze o nazwiet
. Ciąg następujący po nim jest sekwencją klucza.bind t
wiąże się z kluczem t(tzn. wykonuje za pomocą Ctrl+ at),process t
oznacza ocenę zawartości wymienionego buforat
.^a[
(= Ctrla[): wejdź w tryb kopiowaniak
przejdź o jedną linię w górę,0
przejdź na początek linii,y$
kopiuj do końca linii, (spacja) wykonaj polecenie^a]
(= Ctrla]): wklej skopiowaną treść^a^L
(= CtrlaCtrlL) odśwież ekran (w przeciwnym razie wklejona zawartość nie pojawi się, ponieważ nie wpisałeś jej samodzielnie)źródło