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?


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


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)"

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.


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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.