Jak wykonywać kolejne polecenia z historii?

49

Załóżmy, że chcę wykonać sekwencję czterech poleceń, które wcześniej wykonałem. Jeśli pierwszy to 432 w historii poleceń, mógłbym zrobić:

$ !432; !433; !434; !435

Jestem ciekawy, czy istnieje bardziej skuteczny sposób na osiągnięcie tego?

Eric Wilson
źródło
1
Nie publikowanie tego jako odpowiedzi, ponieważ nie wykonuje poleceń, ale możesz napisać, history -p \!43{2..5}aby wydrukować polecenia od 432 do 435 na terminalu, odpowiednie do późniejszego kopiowania / wklejania.
Wildcard

Odpowiedzi:

48

Jeśli odnosi się do ostatnio uruchomionych poleceń, bardziej efektywnym sposobem jest odniesienie ich do liczb ujemnych:

!-4; !-3; !-2; !-1

Ponadto, gdy to zrobisz, twój ostatni wpis historii będzie zawierał cały łańcuch poleceń, więc możesz to powtórzyć !!.


Edycja: Jeśli jeszcze tego nie zrobiłeś, zapoznaj się ze wspaniałą wbudowaną funkcją fc, o której wspomniał Gilles . (Użyj help fc.) Okazuje się, że możesz również używać liczb ujemnych, więc możesz zrobić to samo, co powyżej, używając

eval "`fc -ln -4 -1`"

Ma to jednak jedno zastrzeżenie: po tym evalwiersz jest zapisywany w historii jako ostatnie polecenie. Więc jeśli uruchomisz to ponownie, wpadniesz w pętlę!

Bezpieczniejszym sposobem na to jest użycie domyślnego fctrybu działania: przekazanie wybranego zakresu poleceń do edytora i uruchomienie ich po wyjściu z niego. Próbować:

 fc -4 -1

Możesz nawet odwrócić kolejność zakresu poleceń: fc -1 -4

rozcietrzewiacz
źródło
Właśnie przeczytałem, co napisałem ... LOL. Faktycznie, nie jestem pewien o reinvoke ( reinvoke może?), Ale dzięki za informację :) ja zawsze doceniają korekt.
rozcietrzewiacz
Scrabblefinder.com mówi, że reinvoke jest prawidłowym słowem Scrabble. Nie można uzyskać bardziej ostatecznego niż to. :)
BentFX,
1
Przy dobrej odpowiedzi takiej jak ta (+1) nie ma znaczenia, jak ją przeliterujesz; tym bardziej, że żadna forma pisowni nie pojawia się w 3 głównych słownikach: Oxford, Camgridge, Merriam-Webster (
wybrałbym
34

Aby wyświetlić zakres poleceń w historii, użyj wbudowanego fcpolecenia:

fc -ln 432 435

Aby wykonać je ponownie:

eval "$(fc -ln 432 435)"
Gilles „SO- przestań być zły”
źródło
4
Bardzo dobrze. Jestem ciekawa, dlaczego man fcnic mi nie daje. Co oznacza fcskrót Jakie są inne opcje?
Eric Wilson,
2
@Eric Wilson ... wpisz help fc... a także help help.... help: help [-dms] [pattern ...] Wyświetla informacje o wbudowanych poleceniach.
Peter.O,
Właśnie wróciłem tutaj, szukając twojej odpowiedzi. To naprawdę jest świetne wbudowane! Zwłaszcza, gdy jest to domyślna funkcja - wywoływanie edytora w celu zmodyfikowania zakresu poleceń do odtworzenia. Dzięki, Gilles.
rozcietrzewiacz
1
Bez -lflagi wykona się bez potrzeby zła eval.
Bernhard,
1
@EricWilson Wyszukiwarka google zaprowadziła mnie do książki „Unix in a Nutshell”, która fcoznacza „znajdź polecenie” lub „napraw polecenie”.
Slothworks,
10

Istnieje przyjemny i alternatywny sposób uruchamiania wielu poleceń w sekwencji z historii Bash:
zamiast używać zastępowania historii ( !432lub !-4), możesz przeszukiwać historię za pomocą Ctrl+ r, a gdy znajdziesz pierwsze polecenie, które chcesz uruchom, naciśnij Ctrl+ o( operuj i idź dalej ) zamiast returnklawisza
Spowoduje to uruchomienie polecenia i zaproponowanie następnego z historii. Możesz trafić Ctrl+otyle razy, ile chcesz i zakończyć sekwencję albo returnna ostatnią, albo Ctrl+czatrzymać się bez uruchamiania.

Cyryl Chaboisseau
źródło
Hmm, po tym, jak uderzyłem, po Ctrl-oprostu wysyła literał ^oi łamie mój (reverse-i-search). Może wiąże się to z innymi ustawieniami.
Ciro Santilli 事件 改造 中心 法轮功 六四 事件 事件
8

Aby natychmiast wykonać polecenia zamiast je edytować, oto syntaktycznie cieńsza wersja odpowiedzi Gilesa z użyciem eval :

fc -e: 432 435

Argument dwukropka -e to bash noop, który powoduje pominięcie kroku „otwórz w edytorze”, którego chce fc. Ponadto, teraz (najnowsza) historia będzie zawierać rzeczywiste polecenia z historii, a nie instrukcję eval.

użytkownik1543542
źródło
0

fc dla pętli i xsel

Działa to dobrze, gdy chcę połączyć i ponownie uruchomić ostatnie n poleceń wiele razy:

fcn() (
  from="${1:-2}"
  to="${2:-1}"
  if [ "$from" -ne "$to" ]; then
    for i in `seq "$from" -1 "$(($to + 1))"`; do
      printf "$(fc -ln -${i} -${i}) && "
    done
  fi
  printf "$(fc -ln -${to} -${to})"
)

Następnie:

$ echo a
a
$ echo b
b
$ echo c
c
$ fcn 3 1 | xsel -b
$ # Paste.
$  echo a &&  echo b &&  echo c
a
b
c
$ # Paste again if you feel like it.
$  echo a &&  echo b &&  echo c
a
b
c

Lub w przypadku większych poleceń, które mogą wymagać edycji:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
Ciro Santilli
źródło