Come eseguire comandi consecutivi dalla cronologia?


49

Supponiamo di voler eseguire una sequenza di quattro comandi che ho eseguito in precedenza. Se il primo è 432 nella cronologia dei comandi, allora potrei fare:

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

Sono curioso, c'è un modo più efficiente per raggiungere questo obiettivo?


1
Non pubblicare questa come risposta perché non esegue i comandi, ma è possibile digitare history -p \!43{2..5}per stampare i comandi da 432 a 435 sul terminale, adatti per la successiva copia / incolla.
Wildcard il

Risposte:


48

Se si riferisce ai comandi eseguiti solo di recente, un modo più efficiente è fare riferimento a loro con numeri negativi:

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

Inoltre, una volta che lo fai, l'ultima voce della cronologia conterrà l'intera catena di comandi, quindi puoi ripeterla con !!.


Modifica: se non lo hai già fatto, acquisisci familiarità con la grande funzione integrata fc, menzionata da Gilles . (Usa help fc.) Si scopre che puoi anche usare numeri negativi con esso, quindi puoi fare lo stesso di sopra usando

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

Questo ha un avvertimento, tuttavia: dopo questo, la evalriga viene memorizzata nella cronologia come ultimo comando. Quindi, se lo esegui di nuovo, cadrai in un ciclo!

Un modo più sicuro per farlo è utilizzare la fcmodalità operativa predefinita : inoltrare l'intervallo di comandi selezionato a un editor ed eseguirli una volta usciti da esso. Provare:

 fc -4 -1

Puoi anche invertire l'ordine dell'intervallo di comandi: fc -1 -4


Ho appena letto quello che avevo scritto ... LOL. In realtà, non sono sicuro di reinvocare ( ri-invocare forse?), Ma grazie per avermelo detto :) Apprezzo sempre le correzioni.
rozcietrzewiacz,

Scrabblefinder.com afferma che reinvoke è una parola Scrabble valida. Non posso essere più definitivo di così. :)
BentFX,

1
Con una buona risposta come questa (+1), non importa come si scrive; soprattutto perché nessuna forma di ortografia compare in 3 principali dizionari inglesi: Oxford, Camgridge, Merriam-Webster (vorrei andare per il trattino)
Peter.O

34

Per visualizzare una serie di comandi nella cronologia, utilizzare il fccomando integrato :

fc -ln 432 435

Per eseguirli di nuovo:

eval "$(fc -ln 432 435)"

4
Molto bella. Sono curioso però, perché man fcnon mi dà niente. Cosa significa fc? Quali altre opzioni ci sono?
Eric Wilson,

2
@Eric Wilson ... digita help fc... e anche help help.... help: help [-dms] [pattern ...] Visualizza le informazioni sui comandi integrati.
Peter

Sono appena tornato qui, alla ricerca della tua risposta. Questo è davvero un ottimo strumento! Soprattutto quando si è la sua funzionalità predefinita: invocare un editor per modificare una gamma di comandi da riprodurre. Grazie Gilles.
rozcietrzewiacz,

1
Senza -lbandiera, verrà eseguito senza bisogno del male eval.
Bernhard

1
@EricWilson Una ricerca su Google mi porta al libro "Unix in a Nutshell" che dice fcsta per "trova comando" o "correggi comando".
Slothworks,

10

C'è un modo simpatico e alternativo per eseguire un numero di comandi in sequenza dalla cronologia di Bash:
invece di usare il sostituto della cronologia ( !432o !-4), puoi cercare nella cronologia con Ctrl+ re una volta trovato il primo comando che desideri corri, premi Ctrl+ o( operare-e-ottenere-prossimo ) invece del returntasto
Questo avvierà il comando e proporrà il prossimo dalla storia. Puoi colpire Ctrl+otutte le volte che vuoi e terminare la sequenza con returnper l'ultima, oppure Ctrl+cfermarti senza avviarla.


Hmm, dopo averlo colpito Ctrl-oemette solo un valore letterale ^oe rompe il mio (reverse-i-search). Forse c'è qualche altra impostazione coinvolta.
Ciro Santilli 11 改造 中心 法轮功 六四 事件

8

Per eseguire immediatamente i comandi anziché modificarli, ecco una versione sinteticamente più sottile della risposta di Giles usando eval :

fc -e: 432 435

L'argomento due punti a -e è il bash noop, che ha l'effetto di saltare il passaggio "apri in un editor" che fc vuole. Inoltre, ora la (recente) cronologia conterrà i comandi effettivi della cronologia, anziché l'istruzione eval.


0

fc per loop e xsel

Funziona bene quando voglio concatenare ed eseguire nuovamente gli ultimi n comandi più volte:

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

Poi:

$ 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

O per comandi più grandi che potrebbero richiedere alcune modifiche:

fcn 3 1 >cmds.sh
vi cmds.sh
bash cmds.sh
bash cmds.sh
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.