Cerca un comando precedente con il prefisso che ho appena digitato


67

Possiamo usare le frecce su e giù per navigare nella cronologia dei comandi.

In alcuni IDE, come Matlab, se immettiamo qualcosa e poi premiamo i tasti freccia, scorriamo solo tra i comandi della cronologia a partire da ciò che abbiamo inserito. È davvero conveniente, ma in un terminale shell non funziona.

C'è un modo per ottenere una funzione simile in un terminale shell? E altri suggerimenti per migliorare l'efficienza nell'uso dei terminali?


Potresti semplicemente usare una shell che fornisce tale funzionalità, come fish;)
yoann

@yoann stai supponendo che bash no. Tramite readline, non è accessibile per impostazione predefinita.
muru,

@muru Sono a conoscenza di CTRL + R in bash, e la risposta di egmont fornisce un modo pulito per farlo con Pagina su / Pagina giù. Esiste tuttavia un modo per farlo con i tasti freccia?
giovedì

1
@yoann controlla unix.stackexchange.com/a/76591/70524 . Invece di \e[5~e \e[6~, uso \e[A, \e[B.
muru,

Risposte:


95

Quello che stai cercando è CtrlR.

Digitare CtrlRe quindi digitare parte del comando desiderato. Bash mostrerà il primo comando corrispondente. Continua a digitare CtrlRe bash scorrerà i precedenti comandi corrispondenti.

Per cercare all'indietro nella cronologia, digita CtrlSinvece. (Se CtrlSnon funziona così per te, ciò probabilmente significa che devi disabilitare il controllo del flusso XON / XOFF: per farlo, esegui stty -ixon.)

Questo è documentato in "Ricerca" in man bash.


1
Ctrl-Qper uscire dallo stato di congelamento, se hai già colpito Ctrl-Ssenza disattivare prima il controllo del flusso e hai bloccato il terminale.
HongboZhu

26

Metti questi nel tuo ~/.inputrc:

"\e[5~": history-search-backward
"\e[6~": history-search-forward

Questi fanno Page Upe si Page Downcomportano come desideri. (Alcune distribuzioni lo hanno già configurato per te.) Personalmente trovo questo modo più conveniente di Ctrl+ Ro history.


Questo è il modo più conveniente in tutte le risposte attuali. Potresti dare una piccola spiegazione sul meccanismo di funzionamento?
Lee,

3
~/.inputrcoppure /etc/inputrcoppure il file a cui fa riferimento la variabile d'ambiente $INPUTRCè il file di configurazione per la modifica della linea di tutte le applicazioni che usano readline, incluso bash (la shell). Ha alcune funzionalità integrate di modifica delle linee, tra cui queste due: nella ricerca della pagina del manuale di bash per una di queste parole chiave per saperne di più. \e[5~/ \e[6~sono le sequenze di escape generate dai tasti Pagina su / giù nella maggior parte degli emulatori di terminale; per vederlo, avviare il catcomando e quindi premere questi tasti (il byte di escape è rappresentato nel terminale come ^[, in inputrc come \e).
egmont,

L'esempio nella domanda originale dice che i tasti Su / Giù funzionano in questo modo in Matlab. Sarebbe interessante vedere cosa è successo se hai inserito la sequenza di Su e Giù in inputrc e ti sei assegnato a questa azione; funzionerebbe correttamente o avrebbe effetti collaterali sgradevoli in quanto in conflitto con il loro comportamento predefinito. Non lo so, sarei felice di ascoltare le tue scoperte se sperimentassi con questo.
egmont,

Quando lo faccio echo $INPUTRCè vuoto. Sto usando Ubuntu 14.04
JorgeeFG il

2
Personalmente preferisco "\e[A": history-search-backward"\e[B": history-search-forward
scavalcare

9

Oltre alla storia di ^ r / ^ i-search:

alt.inserisce l'ultima "parola" del comando precedente sul cursore. Ripetilo per ottenere l'ultima parola dai comandi più vecchi. (Ma nota che un trailing &conta come l'ultima parola per i comandi in background).

Questo è super utile per mkdir foo, cdalt-dot. Anche più veloce di freccia in alto, ^ a, alt-d (cancellare parola in avanti), cd.

Per ottenere la penultima parola, usa esc - 2 alt+.(es. Usa un argomento numerico in stile emacs per alt+.. Conteggio negativo dalla fine, conteggi positivi in ​​avanti dall'inizio.) Ma di solito questo è più un problema che un valore; ad un certo punto è più veloce raggiungere il mouse e copiare / incollare, o freccia su e ^ w / ^ y parte di esso (vedi sotto).


Se il tuo terminale è impostato in modo corretto / corretto, ctrl-sinistra e ctrl-destra andranno avanti / indietro di parole. In caso contrario, si spera che almeno alt-b e alt-f facciano la stessa cosa.


ctrl- / è un annullamento. È possibile utilizzare la ripetizione automatica per eliminare le parole in modo molto più efficiente se è possibile annullare quando si supera un po 'di tempo.


Il mixaggio / abbinamento più potente dei comandi deriva dall'uso del kill-ring, che funziona proprio come in Emacs. ctrl-y per incollare l'ultimo ctrl-w / ctrl-u / ctrl-backspace / alt-d. alt-y per scorrere il testo ucciso più vecchio.

Più ctrl-w o qualsiasi altra cosa in una riga compongono la voce kill-ring. Utilizzare la freccia sinistra e destra o qualcosa per spezzare la voce se si desidera rimuovere due elementi e incollarne uno solo in seguito.

Combinando tutti questi insieme, puoi

  • inizia a digitare un comando
  • ctrl-r per tornare a un vecchio comando e afferrarne una parte con control-w o simile.
  • esc-r o alt+rper ripristinarlo com'era prima di eliminarne una parte.
  • alt- >per andare alla fine della storia (cioè freccia giù fino in fondo), per tornare al comando in cui ti trovavi nel mezzo.

Altri suggerimenti per l'uso interattivo:

Abilita shopt -s globstar, quindi puoi farlo **/*.c(ricorsivo inclusa la directory corrente). A volte utile per l'uso interattivo, ma di solito find -name '*.c' -exec foo {} +è meglio.

Se scrivi script bash, ti sarà utile averlo shopt -s extglobabilitato anche nelle tue shell interattive. A volte troverai un uso per cose come *.!(c|h)abbinare file che non finiscono con .c o .h.

Trova alias ti piace per ls -l, lesse qualsiasi altra cosa si fa un sacco. ( cp -i, mv -ie rm -Isono carini. Non prendere l'abitudine di dipendere da loro per fare un rm selettivo. GNU rm's -Io chiedo una volta per tutte le discussioni.)

Mi piace alias m=less(m per "altro"). Ho lessimpostato ,e .associato al file precedente / successivo ( lesskey). L'impostazione predefinita è una sequenza multi-tasto che non può essere utilizzata con autorepeat.


Mi piace fare tutto all'interno dello schermo GNU. Trovo più facile tenere traccia delle finestre numerate dello schermo rispetto a un carico di schede in Konsole (o qualsiasi altro emulatore di terminale che ho provato). Se non lo sai già screen, impara tmux perché è più recente e meno croccante.

Per ottenere qualcosa di simile alla funzionalità di apertura di una nuova shell con lo stesso cd di un'altra shell, uso un hook personalizzato per cd / pushd / popd che mi permette di fare cds 8cd in qualunque dir la mia shell nella finestra dello schermo 8 sta usando. Funziona anche con shell al di fuori della sessione dello schermo, purché ci sia solo una sessione dello schermo.


Il mio non sembra essere "correttamente configurato". Molte delle scorciatoie che vedo qui non funzionano, sto usando Terminale stock di Ubuntu 14.04. Come posso configurarlo?
JorgeeFG,

@JorgeeFG: Penso che abbia funzionato per me con gnome-terminalUbuntu 14.04, prima di passare a KDE. L'opzione pertinente è nelle impostazioni del terminale, prefisso esc vs high-bit e forse alcune altre impostazioni. Alcuni di loro non funzionano perfettamente per me attraverso ssh. (es. ctrl sinistra / destra munge il codice di escape per il tasto freccia e mi 5Dappare letteralmente)
Peter Cordes,

7

Aggiungi le seguenti righe al tuo ~/.inputrc

"\e[A": history-search-backward
"\e[B": history-search-forward

Questo è simile alla risposta di egmont, ma invece di usare Pagina su e Pagina giù, usa le sequenze di escape per Freccia su e Freccia giù. In questo modo è molto più comodo da usare su un Mac.


4

Tendo sempre a configurare le mie macchine con un grande valore HISTSIZE in modo che mantenga un elenco cronologico più lungo, così come HISTTIMEFORMAT con il valore del timestamp in modo da poter vedere quando è stato eseguito il comando.

export HISTSIZE=10000
export HISTTIMEFORMAT="%m/%d/%Y %T "

3

Il mezzo che di solito uso è combinare il historycomando congrep

IE:

history | grep <command im looking for>

Verrà visualizzata una cronologia numerata dei comandi digitati che contengono quel comando, quindi puoi utilizzare:

!<number listed in history command>

per ripetere quel comando.

IE:

history | grep history

142  history
143  history | grep lvresize
568  history | grep echo
570  history | grep echo
571  history | grep history

seguito da: !571

ripeterò history | grep history


1
CR = molto meglio + molto più sicuro
PSkocik,

1
Forse, personalmente trovo che una storia convogliata su grep sia un mezzo più veloce per trovare la maggior parte dei comandi. Per quanto riguarda Safer, non sono sicuro di cosa tu voglia dire, quali sono i rischi intrinseci nell'uso della storia rispetto alla sua ricerca con CR?
Sugo

2
@Gravy Sospetto che PSkocik significhi che la !sostituzione della cronologia è meno sicura.
derobert,

3
@Gravy I rischi intrinseci sarebbero accidentalmente la linea sbagliata. Non ho idea del perché il tuo terminale si sia bloccato, a meno che tu non abbia usato Control-S e tu abbia il controllo del flusso xon / xoff abilitato (spesso il valore predefinito). In tal caso, Control-Q lo riporterà.
derobert,

1
Sono d'accordo con @PSkocik, cr è molto meglio perché è più semplice modificare la linea della cronologia, piuttosto che eseguirla di nuovo allo stesso modo. Eseguire di nuovo lo stesso comando è un banale caso di cosa si può fare per risparmiare tempo a riscrivere le variazioni su una riga complessa o completare una scheda in un lungo percorso. Vedi la mia risposta
Peter Cordes,

1

Ho usato quotidianamente 4 suggerimenti (e alcuni altri) nel mio terminale Bash:

  • Esegui l'ultimo comando: !!

  • Esegui il comando N dalla cronologia: !N

  • Stampa l'ultimo comando che inizia con il prefisso dalla cronologia: !prefix:p

  • Esegui l'ultimo comando iniziando con il prefisso dalla cronologia: !prefix


1

Se per te è OK usare al zshposto bashtuo cona usa oh-my-zsh per quello.

Contiene la freccia su giù nella navigazione nella cronologia dei comandi. Permette anche quella stessa navigazione quando hai già digitato del testo (come Mathlab).

modifica: contiene anche altre cose focalizzate sullo sviluppatore, come alias e temi. Questi extra rendono la distribuzione più grande e più complessa da usare.

https://github.com/robbyrussell/oh-my-zsh


1
oh-my-zshcontiene tonnellate di roba. Potresti anche dire: questa funzione esatta è inclusa in quella distribuzione, quando tutto ciò di cui hai bisogno è un'impostazione o un'app specifica.
muru,

Ho modificato il post: ho avvertito che è più grande di una semplice app.
user9869932

1

Aggiungi il seguente alias a ~ / .bashrc

alias h='history | awk '"'"'{$1="";print}'"'"' |sed "s/^ *//" |grep -v "^h " | sort | uniq | grep'

Uso: h firemi porterà un elenco di comandi contenenti fuoco . o h ^firemi porterà un elenco di comandi che iniziano con il fuoco .

Questo è utile quando voglio visualizzare una serie di comandi contemporaneamente.

A proposito, '"'"'è brutto ma non sono riuscito a trovare altri modi per evitare virgolette singole tra virgolette singole.


a proposito: h="history | awk '{\$1=\"\"; print}'dovrebbe funzionare. in alternativa, crea una funzione e chiamala.
DarkHeart,

grazie DarkHeart, ma ho provato il tuo codice, ho scoperto che non ha funzionato nel mio ambiente, forse c'è qualcosa di diverso nel mio
Hosi Golden,
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.