Noterai che quando esegui cat
un prompt della shell su un terminale, cat
dovendo scrivere a stdout ciò che legge da stdin, e premi a, vedi un a
eco restituito dal driver del terminale, ma cat
non lo scrive a
(vedi solo uno a
, quello echeggiato dal driver del terminale).
Tuttavia, se digiti a Backspace b Enter, non vedi l' cat
output a\010b\015
, ma b\012
( b
e la nuova riga).
Questo perché il driver del terminale (stiamo parlando di software nel kernel, non nell'emulatore di terminale come xterm
) implementa un editor di linee molto semplice quando è in modalità canonica . Il driver del terminale può essere configurato utilizzando ioctl()
le chiamate di sistema come quando si utilizza il stty
comando. Ad esempio, per uscire dalla modalità canonica, puoi farlo stty -icanon
. Se fate:
stty -icanon; cat
Quindi vedrai sia l' output echo
(con il quale potresti aver disabilitato stty -echo
) sia l' cat
output.
Quell'editor è un editor di linee. Cioè, spetta all'utente modificare una riga di testo fino a quando non viene inviato all'applicazione leggendo il dispositivo terminale dopo aver premuto Enter.
Le capacità di modifica di quell'editor sono molto limitate. Nella maggior parte delle implementazioni, ci sono solo 4 chiavi di modifica (in realtà caratteri) configurabili anche con stty
:
- cancella (
^H
o di ^?
solito): cancella il carattere precedente
- kill (di
^U
solito): svuota (uccide) la riga inserita finora
- werase (
^W
): cancella la parola precedente
- lnext (
^V
): inserisci il carattere successivo letteralmente (annulla il significato speciale di tutto quanto sopra)
Ai vecchi tempi, si pensava che quell'editor di linea del driver terminale sarebbe stato esteso con funzionalità più elaborate. Questo è il motivo per cui nessuna delle prime shell ha funzionalità di modifica della riga di comando (al prompt della shell si otterrebbero le stesse funzionalità di modifica della riga rispetto a quando si esegue cat
come descritto sopra).
Tuttavia, ciò non è mai accaduto, forse parte del motivo è che il caos con terminali diversi non ha inviato gli stessi caratteri su alcune pressioni di tasti, il che ha reso evidente che non dovrebbe essere implementato nello spazio del kernel.
Quindi alcune shell hanno iniziato a abbandonare la modalità canonica del driver del terminale e ad implementare il proprio editor di linee. A quel tempo, emacs
e vi
sono stati i più popolari editor di testo visivo con la modalità di rilegatura chiave e il funzionamento completamente diverso. In vi
, hai una modalità per l'immissione del testo e una per la modifica. In emacs
, stai sempre entrando in modalità testo , ma la modifica viene effettuata premendo le combinazioni di tasti (come ^b
spostare il personaggio all'indietro).
All'epoca non aveva senso che le shell trovassero il loro diverso key binding. Ciò avrebbe causato frustrazione alle persone che dovevano imparare qualcosa di diverso. Tuttavia, scegliere uno ( emacs
o vi
) stile rispetto all'altro sarebbe stato un modo sicuro per alienare gli utenti dell'altro editor.
Secondo https://www.usenix.org/legacy/publications/library/proceedings/vhll/full_papers/korn.ksh.a :
Le popolari funzionalità di modifica in linea (modalità vi ed emacs) di ksh sono state create dagli sviluppatori software dei Bell Laboratories; la modalità di modifica della linea vi di Pat Sullivan e la modalità di modifica della linea emacs di Mike Veach. Ognuno aveva modificato in modo indipendente la shell Bourne per aggiungere queste funzionalità, ed entrambi facevano parte delle organizzazioni che volevano usare ksh solo se ksh aveva il loro rispettivo editor inline. Inizialmente l'idea di aggiungere la modifica della riga di comando a ksh è stata respinta nella speranza che la modifica della riga si spostasse nel driver del terminale. Tuttavia, quando è diventato chiaro che ciò non sarebbe successo presto, entrambe le modalità di modifica della linea sono state integrate in ksh e rese opzionali in modo da poter essere disabilitate sui sistemi che fornivano l'editing come parte dell'interfaccia del terminale.
Quindi, invece, hanno implementato entrambi e un'interfaccia per gli utenti di scegliere tra i due. ksh
fu probabilmente il primo nei primi anni '80 (riutilizzando il codice che era stato scritto separatamente per aggiungere una modalità vi e una modalità emacs alla shell Bourne come visto sopra) seguito da tcsh
( tcsh
inizialmente aveva solo l' emacs
associazione delle chiavi, la vi
modalità fu aggiunta in seguito) e successivamente bash
e zsh
nei primi anni '90.
Si passa tra le due modalità in bash
, zsh
o ksh
con set -o vi
o set -o emacs
, e con bindkey -e
o bindkey -v
in tcsh
o zsh
.
POSIX in realtà specifica la vi
modalità e non la emacs
modalità per sh
(la storia ha che Richard Stallman si è opposto a POSIX specificando la emacs
modalità persh
).
La modalità predefinita per bash
, le varianti di dominio pubblico di ksh
(pdksh, mksh, oksh), tcsh
ed zsh
è la modalità emacs (sebbene con zsh
, è vi
se lo $EDITOR
è vi
), mentre in AT&T ksh
, è la modalità stupida a meno che $EDITOR
o $VISUAL
menzioni vi
o emacs
.
ksh
inoltre in seguito ha aggiunto una gmacs
modalità per soddisfare gli utenti di Gosling emacs
che ha gestito in modo Ctrl+Tdiverso.
Ora la gestione della modalità ^W
in emacs
o in tcsh
emacs probabilmente precede il werase
carattere nell'editor della linea terminale, quindi non possiamo davvero biasimarli per questo e la mia affermazione su "partire ..." può essere vista come fuorviante. E 'solo che trovo irritante quando le cose come emacs
, tcsh
o info
comportarsi in modo diverso da tutto il resto quando si digita Ctrl-W. Puoi immaginare che l'ho trovato molto più irritante quando alcune applicazioni hanno iniziato a chiudere la finestra quando hai digitato Ctrl-W.