Scorciatoia da tastiera della cronologia di Bash per! *


8

In Bash, ci sono alcuni operatori utili per ripetere parti dell'ultimo comando:

  • !^ si espande al primo argomento del comando precedente, ad es.

    $ echo one "two three"
    one two three
    $ echo !^
    echo one
    one
  • !$ si espande all'ultimo argomento del comando precedente, ad es.

    $ echo one "two three"
    one two three
    $ echo !$
    echo "two three"
    two three
  • !* si espande a tutti gli argomenti del comando precedente, ad es.

    $ echo one "two three"
    one two three
    $ echo !*
    echo one "two three"
    one two three

(Per quanto ho capito, si tratta di zucchero sintattico per e !!:^, rispettivamente, dove si trova un designatore di eventi che si espande al comando precedente e , e che sono designatori di parole, consultare il Manuale di riferimento di Bash o .)!!:$!!:*!!^$*man bash

Questi sono spesso abbastanza utili. Ma diventa ancora più interessante con le scorciatoie da tastiera:

  • Quando si preme Alt+ .o Alt+ _, l'ultimo argomento del comando precedente viene inserito nel comando corrente, analogamente come se si fosse scritto !$a quel punto.

  • È anche possibile premere Alt+ Ctrl+ yper inserire il primo argomento del comando precedente, come se avessi scritto !^a quel punto.

(Vedi la libreria GNU Readline o info readline.)

Tendo a preferire le scorciatoie da tastiera rispetto agli operatori della cronologia di Bash, perché posso vedere cosa sto inserendo prima di eseguire effettivamente il comando. Tuttavia, non sembra esserci una scorciatoia che mi permetta di inserire tutte le parole del comando precedente, vale a dire una che fa !*il lavoro. Almeno non sono riuscito a trovarlo.

C'è una tale scorciatoia? In caso contrario, è possibile configurare la libreria readline per aggiungerne una e come?


AFAIK, le scorciatoie da tastiera sono gestite dall'emulatore di terminale. Quindi suppongo che tu stia usando gnome-terminal?
Seth,

1
In zsh, se si digita echo !*e quindi si preme TAB, si ottiene l'effetto desiderato. In generale, TAB mentre in readline espanderà tutto l'espandibile. Molto maneggevole; probabilmente bash avrà qualche configurazione con lo stesso effetto? @Seth, penso che questo sia il readline in bash, non l'emulatore di terminale - non sono sicuro però.
Rmano,

2
@Seth No, le scorciatoie dalla Q sono gestite da bash. Puoi cercare "Comandi per manipolare la storia" in man bash(da qualche parte alla linea 3030)
Radu Rădeanu,

@ RaduRădeanu Oh interessante! Non lo sapevo. Il mio male per i cattivi presupposti.
Seth,

1
\e.e \e_sono mappati sulla funzione readline yank-last-arged \e\C-yè mappato su yank-nth-arg. Purtroppo non sembra esserci alcun comando (singolo) che aggiunge più argomenti precedenti contemporaneamente.
Adaephon

Risposte:


5

Se guardi l'output del seguente comando:

bind -l

o meglio a:

bind -l | grep arg

puoi vedere che non esiste alcuna funzione readline per tutti gli argomenti come è, ad esempio, yank-last-argper l'ultimo argomento - che può inserire l'ultimo argomento nel comando precedente (l'ultima parola della voce della cronologia precedente). Quindi, se tale funzione non esiste, molto probabilmente non esiste una scorciatoia per realizzare ciò che desideri.

Proviamo a creare uno che si avvicina alla tua richiesta ...

Innanzitutto, guarda ad esempio l'output del seguente comando:

bind -p | grep yank-nth-arg

L'output è:

"\e\C-y": yank-nth-arg

e può essere tradotto come segue: yank-nth-arg(che inserisce il primo argomento nel comando precedente - con un argomento n, inserisce l'ennesimo argomento dal comando precedente) è associato a Alt+ Ctrl+ y.

Allo stesso modo può essere interpretata qualsiasi riga dall'output del bind -pcomando.

Ora fai attenzione ai seguenti scenari:

  • Se si imposta la seguente associazione:

    bind '"\ea": "\e2\e."'

    Alt+ Asarà mappato su Alt+ 2Alt+ .che è mappato per inserire il secondo argomento del comando precedente. Quindi, dopo aver premuto Alt+ A, il secondo argomento del comando precedente viene inserito nel comando corrente.

  • Se imposti:

    bind '"\ea": "\e1\e. \e2\e."'

    Dopo aver premuto Alt+ A, i primi due argomenti del comando precedente vengono inseriti nel comando corrente. Se il numero degli argomenti del comando precedente è massimo 2, ovviamente tutto il comando precedente viene inserito nel comando corrente.

  • Se imposti:

    bind '"\ea": "\e1\e. \e2\e. \e3\e."'

    Dopo aver premuto Alt+ A, i primi tre argomenti del comando precedente vengono inseriti nel comando corrente. Se il numero degli argomenti del comando precedente è massimo 3 (come nel tuo caso), ovviamente tutto il comando precedente viene inserito nel comando corrente.

  • E così via.

Per i primi 10 argomenti, puoi usare:

bind '"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."'

E penso che questo sia abbastanza lungo per quanto non uso troppo spesso i comandi con così tanti argomenti.

Per renderlo persistente, aggiungi la seguente riga al tuo ~/.inputrcfile:

"\ea": "\e1\e. \e2\e. \e3\e. \e4\e. \e5\e. \e6\e. \e7\e. \e8\e. \e9\e. \e1\e0\e."

In questo esempio ho scelto Alt+ Aper inserire tutti gli argomenti (se il numero di argomenti non è maggiore di 10) del comando precedente, ma puoi scegliere qualsiasi altra combinazione con te sostituendo nel comando precedente la \eastringa.

risorse:


Bene, è un po 'hacker, e funzionerà solo per un numero limitato di argomenti, ma sembra essere il più vicino che possiamo facilmente ottenere - lo prenderò;) In realtà ho appena dato un'occhiata al codice sorgente di readline. A prima vista sembra che nel file funmap.c, la funzione yank-nth-argsia mappata sulla funzione C rl_yank_nth_arg, che a sua volta è definita in kill.c. Analogamente per yank-last-arg. Naturalmente sarebbe possibile estendere readline con una tale funzionalità, ma non voglio farlo; Preferisco che la mia readline sia gestita da apt, e questa funzionalità non è così importante;)
Malte Skoruppa,
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.