Czy istnieje skrót do wykonywania serii poleceń w historii bash?

20

Załóżmy, że mam następujący trywialny przykład history:

...
76 cd ~
77 ./generator.sh out.file
78 cp out.file ~/out/
79 ./out/cleaner.sh .
80 ls -alnh /out
...

Jeśli chciałbym wykonywać polecenia 77, 78i 79w jednym poleceniu, czy istnieje do tego skrót? Próbowałem !77 !78 !79, który po prostu umieści je wszystkie w jednym wierszu do wykonania.

MrDuk
źródło
9
Jest w !77 ; !78 ; !79porządku?
thrig
1
Wydaje mi się, że cokolwiek innego niż pisanie wiersz po wierszu jest w porządku, ale !77-79
liczyłem
1
@MDDUK, chłopiec zajął mi trochę czasu, aby zapamiętać. Zobacz moją zaktualizowaną odpowiedź na bardzo zwięzłe rozwiązanie! :)
Wildcard
To magiczne! :)
MrDuk

Odpowiedzi:

28

EDYCJA: Możesz to zrobić w sposób zgodny z POSIX za pomocą narzędzia polecenia fixfc :

fc 77 79

Spowoduje to otwarcie edytora (prawdopodobnie vi) z poleceniami od 77 do 79 w buforze. Po zapisaniu i wyjściu ( :x) polecenia zostaną uruchomione.


Jeśli nie chcesz ich edytować i JESTEŚ BARDZO PEWNY, wiesz, które polecenia wywołujesz, możesz użyć:

fc -e true 77 79

Używa się go truejako „edytora” do edycji poleceń, więc po prostu kończy pracę bez wprowadzania żadnych zmian, a polecenia są uruchamiane bez zmian.


ORYGINALNA ODPOWIEDŹ:

Możesz użyć:

history -p \!{77..79} | bash

Zakłada się, że nie używasz żadnych aliasów, funkcji ani zmiennych, które są obecne tylko w bieżącym środowisku wykonawczym, ponieważ oczywiście nie będą one dostępne w uruchamianej nowej powłoce.


Lepszym rozwiązaniem (dzięki Michaelowi Hoffmanowi za przypomnienie mi w komentarzach) jest:

eval "$(history -p \!{77..79})"

Jeden z bardzo niewielu przypadków, w których evaljest to właściwe!


Zobacz także:

Dzika karta
źródło
2
Nie będzie to działać poprawnie, jeśli dowolne z poleceń zmieni bieżące środowisko wykonywania, np. Zmieniając zmienną lub wykonując polecenie cd, ale jest to przypadek skrajny.
G-Man mówi „Przywróć Monikę”
3
eval "$(history -p \!{77..79})"powinno działać.
Michael Hoffman
1
@MichaelHoffman, myślałem o tym i myślałem, że spróbowałem, ale właśnie zdałem sobie sprawę, że pominąłem cytowanie! Nie! Nic dziwnego, że to nie zadziałało ... edycja odpowiedzi teraz.
Wildcard
14

Prosta odpowiedź: zamiast !77 !78 !79,

  • wpisz polecenie, !77; !78; !79aby zrobić to, co próbujesz zrobić - wykonaj polecenie 77, a następnie polecenie 78, a następnie polecenie 79 bezwarunkowo lub
  • wpisz, !77 && !78 && !79 aby wykonać polecenie 77 i sprawdź, czy się udało. A następnie, jeśli polecenie 77 się powiedzie, wykonaj polecenie 78. A następnie, jeśli polecenie 78 się powiedzie, wykonaj polecenie 79.

Nieco sprytniejsza odpowiedź (jeśli znajdujesz się w oknie typu terminal):

  • Dowiedz się, jaki będzie numer następnego polecenia, które wpiszesz.
    • Można to uwzględnić w monitach; Wierzę, że to przez włączenie \!do twojego PS1.
    • Lub spójrz na swoją historię. Jeśli ostatni wpis to 82 history, następne polecenie to 83.
  • Odejmij 83–77 = 6.
  • Wpisz !-6. Spowoduje to ponowne wykonanie polecenia 77.
  • Wybierz !-6, skopiuj i wklej. Ponieważ ponowne wykonanie komendy 77 ( ./generator.sh) było komendą 83, masz teraz komendę 84, więc !-6ponownie uruchom komendę 78.
  • W razie !-6potrzeby powtórz wklejanie .
G-Man mówi „Przywróć Monikę”
źródło