Jak mogę zapisać ostatnie polecenie do pliku?

29

Kiedy uruchamiam analizy przy użyciu powłoki bash, często chcę zapisać używane polecenia, które dały mi dobre wyniki, do pliku w tym samym katalogu (jak to się nazywa „LOGBOOK”), aby móc sprawdzić, co Zrobiłem, aby uzyskać te wyniki. Do tej pory oznaczało to, że albo kopiuję. Wklejam polecenie z terminala, albo wciskam „w górę”, modyfikując polecenie na inny echo"my command" >> LOGBOOK, lub inny podobny wygłupy.

Odkryłem, że któregoś dnia było historynarzędzie, ale nie mogę znaleźć sposobu na użycie go, aby uzyskać poprzednio wykonane polecenie, aby móc zrobić coś takiego getlast >> LOGBOOK.

Czy istnieje przyjemny i łatwy sposób to zrobić? Alternatywnie, w jaki sposób inni radzą sobie z zapisywaniem poleceń w celu uzyskania wyników?

MattLBeck
źródło

Odpowiedzi:

37

Jeśli używasz bash, możesz użyć fcpolecenia, aby wyświetlić swoją historię w pożądany sposób:

fc -ln -1

To wydrukuje twoje ostatnie polecenie. -loznacza listę, -noznacza , że nie należy poprzedzać wierszy numerami poleceń i -1mówi, aby pokazać tylko ostatnie polecenie. Jeśli spacje na początku wiersza (tylko pierwsza linia w poleceniach wieloliniowych) są uciążliwe, możesz się tego łatwo pozbyć sed. Zrób to z funkcji powłoki, a otrzymasz rozwiązanie zgodnie z żądaniem ( getlast >> LOGBOOK):

getlast() {
    fc -ln "$1" "$1" | sed '1s/^[[:space:]]*//'
}

To powinno działać tak, jak zadałeś pytanie.

Dodałem niewielką zmienność, dodając "$1" "$1"do fcpolecenia. Umożliwi to na przykład getlast mycommandwydrukowanie ostatniego wywołania wiersza poleceń mycommand, więc jeśli zapomniałeś zapisać przed uruchomieniem innego polecenia, nadal możesz łatwo zapisać ostatnią instancję polecenia. Jeśli nie podasz argumentu getlast(tzn. Wywołaj fcjako fc -ln "" "", to wypisze tylko ostatnie polecenie).

[Uwaga: odpowiedź została zredagowana w celu uwzględnienia komentarza @ Bram i problemu wspomnianego w odpowiedzi @glenn jackman.]

camh
źródło
5
Pierwszy formularz fc -lnr | head -n 1można skrócić fc -lnr -1.
Bram
@Bram: Dobre rzeczy. Użyłem help fcdo mojej dokumentacji. Strona podręcznika bash zawiera więcej szczegółów, w tym wykorzystanie ujemnych indeksów. Eliminacja headjest dobra, ponieważ jedno pozostawione polecenie jest wbudowane, więc teraz nie ma rozwidlenia / exec.
camh
1
Zastanawiam się, dlaczego polecenie to nazywa się fc...
imz - Ivan Zachararychev
2
Oznacza „polecenie naprawy”. gnu.org/software/bash/manual/bashref.html#Bash-History-Builtins
Mikel
9

Jednym z problemów z odpowiedzią @ camh jest to, że jeśli masz polecenie obejmujące wiele linii, pokazuje tylko pierwszy wiersz:

$ echo "one
> two
> three"
one
two
three

$ fc -lnr | head -1
         echo "one

Spróbuj tego:

$ alias getlast='fc -nl $((HISTCMD - 1))'

$ echo "one
> two
> three"
one
two
three

$ getlast
         echo "one
two
three"
Glenn Jackman
źródło
3
włączenie cmdhistnaprawi, że: „Jeśli ustawione, bash próbuje zapisać wszystkie wiersze polecenia wieloliniowego w tym samym wpisie historii. Umożliwia to łatwą ponowną edycję poleceń wieloliniowych”.
Mark McKinstry
2

Zamiast używać strzałki w górę, możesz użyć, "!!"aby odwołać się do poprzedniego polecenia.

na przykład

$ some -long --command --difficulty="very hard to remember"
$ echo "!!" >> LOGBOOK

Uwaga: to nie cytuje dosłownego tekstu

ryanbraganza
źródło
5
To nie uchwyci dosłownego polecenia. Jeśli są jakieś metaznaki powłoki, zostaną ocenione i zastąpione. Rurociągi również się zepsują: ls | less-> echo !! >> LOGBOOK-> echo ls | less >> LOGBOOK.
camh
0

Możesz to zrobić za pomocą następującego polecenia, jeśli używasz powłoki bash:

$> history -a LOGBOOK

Spowoduje to dołączenie wszystkich poleceń z bieżącej sesji do tego pliku, możesz również dodać alias do pliku ~ / .bashrc, aby to zrobić za pomocą jednego polecenia:

$> alias getlast="history -a LOGBOOK"
strunowe
źródło
1
Ale brakuje Ci ważniejszego wymogu, że zapisuję tylko te polecenia, które zadziałały i mam wyniki, które mam. Nie chcę zapisywać wszystkich ostatnich poleceń, które wykonałem, po prostu wybierz je po ich użyciu. W każdym razie dzięki.
MattLBeck,