Esiste una scorciatoia per eseguire una serie di comandi nella storia di bash?


20

Supponiamo di avere il seguente esempio banale nel mio history:

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

Se volessi eseguire comandi 77, 78e 79in un comando, esiste un collegamento per questo? Ho provato !77 !78 !79, che li metterà semplicemente su un'unica riga da eseguire.


9
E ' !77 ; !78 ; !79d'accordo?
thrig

1
Immagino che qualsiasi cosa al di fuori della digitazione riga per riga sia ok, ma speravo in qualcosa di un po 'più conciso (sulla !77-79
falsariga

1
@MrDuk, ragazzo mi ci è voluto un po 'di tempo per ricordare. Vedi la mia risposta aggiornata per la soluzione molto concisa ! :)
Wildcard il

È magico! :)
MrDuk,

Risposte:


28

EDIT: puoi farlo in modo conforme a POSIX con lo strumento di comando fixfc :

fc 77 79

Questo aprirà il tuo editor (probabilmente vi) con i comandi da 77 a 79 nel buffer. Quando salvi ed esci ( :x), i comandi verranno eseguiti.


Se non vuoi modificarli e sei MOLTO SICURO di sapere quali comandi stai chiamando, puoi usare:

fc -e true 77 79

Questo utilizza truecome un "editor" per modificare i comandi, quindi esce semplicemente senza apportare modifiche e i comandi vengono eseguiti così come sono.


RISPOSTA ORIGINALE:

Puoi usare:

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

Ciò presuppone che non si stiano utilizzando alias o funzioni o variabili presenti solo nell'attuale ambiente di esecuzione, dato che ovviamente non saranno disponibili nella nuova shell in fase di avvio.


Una soluzione migliore (grazie a Michael Hoffman per avermi ricordato nei commenti) è:

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

Uno dei pochissimi casi in cui evalè effettivamente appropriato!


Vedi anche:


2
Questo non funzionerà correttamente se uno qualsiasi dei comandi modifica l'ambiente di esecuzione corrente, ad esempio modificando una variabile o eseguendo un cd, ma questo è un caso limite.
G-Man dice "Ripristina Monica" il

3
eval "$(history -p \!{77..79})"dovrebbe funzionare.
Michael Hoffman,

1
@MichaelHoffman, ci avevo pensato e pensato di averlo provato, ma mi sono appena reso conto di aver lasciato fuori la citazione! D'oh! Non c'è da stupirsi che non abbia funzionato ... modifica la risposta ora.
Carattere jolly

14

Risposta semplice: invece di !77 !78 !79,

  • digitare !77; !78; !79per fare quello che sembra stia cercando di fare: eseguire il comando 77, quindi il comando 78 e quindi il comando 79, incondizionatamente, oppure
  • digitare !77 && !78 && !79 per eseguire il comando 77 e verificare se è riuscito. E quindi, se il comando 77 ha avuto successo, esegui il comando 78. E poi, se il comando 78 ha avuto successo, esegui il comando 79.

Risposta leggermente più intelligente (se ti trovi in ​​una finestra di tipo terminale):

  • Scopri quale numero di comando sarà il prossimo comando che scrivi.
    • È possibile includerlo nel prompt; Credo che includendo \!nel tuo PS1.
    • Oppure guarda l'elenco della tua cronologia. Se l'ultima voce è 82 history, allora il tuo prossimo comando è 83.
  • Sottrai 83-77 = 6.
  • Tipo !-6. Questo eseguirà nuovamente il comando 77.
  • Seleziona !-6, copialo e incollalo. Poiché la tua riesecuzione del comando 77 ( ./generator.sh) era il comando 83, ora sei sul comando 84, quindi !-6eseguirai nuovamente il comando 78.
  • Ripeti incollando !-6come desiderato.
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.