Come annullare le modifiche nella cronologia dei comandi?


12

Nei sistemi UNIX è possibile premere le frecce superiore e inferiore per navigare attraverso i comandi precedenti. Questo è estremamente utile.

A volte, salgo e trovo un comando che voglio riutilizzare, ma con alcune variazioni. Se faccio tali modifiche, non ho modo di riavere il comando originale, a meno che non lo acceda history.

Esiste un modo per "annullare" le modifiche al comando nella cronologia a cui si accede tramite le chiavi?

La mia attuale soluzione alternativa è anteporre #a al comando. In questo modo il comando corrente viene eseguito come commento, quindi non accade nulla. Quindi, posso navigare di nuovo attraverso i comandi con i tasti. Il problema è che il comando che stavo usando potrebbe essere molto lontano nell'elenco, quindi risalire duecento volte è un po '. Anche Control + R non è una soluzione, dal momento che forse non ricordo esattamente quello che stavo cercando.

Esempio

Ho digitato il seguente "50 comandi fa":

ls -l /etc/httpd/conf/

Ora sono salito su quella linea e l'ho cambiato in

ls -l /etc/init.d/

ma non ha premuto invio. Ora voglio tornare di ls -l /etc/httpd/conf/nuovo.

Il mio ambiente

$ echo $SHELL
/bin/bash
$ echo $TERM
xterm

Il fatto che la cronologia dei comandi venga modificata è probabilmente una (errata) caratteristica della shell che si sta utilizzando. Ad kshesempio, è possibile modificare le voci della cronologia e richiamarle senza eliminare la "versione precedente" della voce; hai tutti i comandi invocati disponibili.
Janis,

Con "cambia" intendo che: dato un comando precedente che ho cambiato dopo averlo raggiunto con le frecce, se vado su e giù con le frecce, il vecchio comando non mostrerà com'era, ma come ho modificato esso. Naturalmente, se digito "invio" eseguendo un comando, quel vecchio comando sarà come inizialmente; ma questo è esattamente ciò che sto cercando di evitare e cerco un modo per "ripristinare" il comando al suo valore iniziale.
fedorqui,

1
Anche in questo caso, kshil comportamento qui differisce, a quanto pare. E le opzioni di modifica della cronologia dipendono anche dalla modalità di modifica scelta. Nella kshmodalità vi, ad esempio, la vecchia voce non viene sovrascritta e posso anche emettere un comando di annullamento, come in vi, con 'u'.
Janis,

Uhm, sembra molto promettente. Ora sto lavorando a Bash e al momento non sto pensando di cambiarlo ksh, ma è bene sapere che esiste qualcosa del genere.
fedorqui,

Vorrei sapere dove bash memorizza la cronologia dei comandi recenti prima di scrivere nel file di cronologia quando la shell è chiusa. Può aiutare a determinare se questo è possibile. Chiunque? Ho pensato che potesse essere in una delle variabili della shell, ma non ho tempo di esaminare il manuale in questo momento.
iyrin,

Risposte:


10

Fintanto che hai modificato una voce della cronologia ma non hai Enterancora premuto , per tornare alla voce originale, premi ripetutamente Ctrl+ _- il undocomando - fino a quando non apporterà ulteriori modifiche. Sei tornato alla voce originale.


5

Ripristina il comando originale dopo aver apportato più modifiche alla riga:

revert-line (M-r) 
    Undo all changes made to this line. This is like 
executing the undo command enough times to get back to the beginning.

Mè la meta chiave, che è altrper me.


Informazioni gratuite, ma utili

Quando si hanno eseguito un comando come OP aveva precedentemente fatto (succede), non c'è nulla da "undo", perché i comandi sono gestite e ricordato dalla GNU Readline biblioteca e sono non scritti$HISTFILE fino a quando le uscite shell. La ragione per cui dico questo è perché non si può semplicemente grepil $HISTFILEcome ci si potrebbe aspettare e non può essere ideale per uscire dal guscio.

Quindi qui ci sono un paio di opzioni per salvarti dallo scorrere indietro attraverso tutti i precedenti comandi readline.

Se ricordi alcuni dei comandi , premi ctrl+ re digita ciò che ricordi per cercare tra i comandi precedenti contenenti quella stringa. Premendo di nuovo ctrl+ rverrà visualizzato il successivo più recente, cercando all'indietro.

Ad esempio, digita ls -lquindi ctrl+ rtante volte quante sono necessarie per trovare il comando precedente che cerchi. Se lo scorri oltre, ctrl+ scercherà in avanti dalla posizione corrente.

Il fccomando incorporato bash è utile per elencare i numeri di indice insieme ai precedenti comandi readline.

fc -l -100 elencherà i precedenti 100 comandi in readline.

Inoltre, se OP sa che sta cercando un ls -lcomando precedente , potrebbe reindirizzare l'output grepcome:fc -l -100 | grep 'ls -l'

Ciò dovrebbe generare un elenco di ls -lcomandi precedenti preceduto da un numero indice. L'output è simile al seguente:
2065 ls -l

Ora puoi usare il designatore di eventi !ndove si ntrova il numero indice. In questo esempio, l'esecuzione !2065si espanderà a ls -l.


Anche se non aiuta dopo il fatto, chiunque cerchi di preservare la cronologia dei comandi recenti quando si modificano i comandi precedenti dovrebbe vedere la HISTORY EXPANSIONsezione di man bash. Ecco alcuni metodi alternativi per modificare i vecchi comandi senza sovrascrivere la cronologia.

La Event Designatorssezione mostra come modificare facilmente la stringa dal comando utilizzato più di recente.

^string1^string2^
              Quick  substitution.  Repeat the previous command, replacing string1 with string2.  Equivalent to
              ``!!:s/string1/string2/'' (see Modifiers below).

Esempio:

$ echo foo
foo 
$ ^foo^bar
echo bar
bar

I comandi più recenti ora mostreranno:

echo foo
echo bar

L'esempio sopra spiega anche come usare sedper sostituire una stringa in un designatore di eventi.

!-n    Refer to the current command minus n.

Quindi se 3 comandi nella cronologia sono, echo fooallora dovresti usare:
!-3:s/foo/bar

Nota che i designatori di eventi appariranno nella tua cronologia come il comando eseguito, in questo caso echo bar. Non comparirà nella storia come !-3:s/foo/bar.

Basta lanciarlo là fuori perché sembra strettamente correlato, anche se è più un "non fare" che la soluzione "annulla" che OP sta cercando.


Questo è carino, molte grazie per le informazioni dettagliate. Accetto la risposta di Gilles poiché fa esattamente quello che sto cercando, mentre qui supponi che io sappia molte cose sul comando che voglio ripetere, il che non è sempre il caso.
fedorqui,

Sì sono d'accordo. Sarebbe bello se quella funzione di annullamento fosse estesa a in precedenza ho inserito i comandi in qualche modo.
iyrin,
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.