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.