Di quale codice di escape ho bisogno in PS * per assicurarmi che il terminale sia tornato nelle normali impostazioni al prompt della shell?


2

A volte accidentalmente catalcuni dati binari; a volte alcuni programmi di ncurses si arrestano in modo anomalo - per molte ragioni il terminale può finire in cattivo stato, richiedendo il manuale reset. Questo succede troppo spesso.

Tale cattivo stato può essere senza eco, o convertire tutto in immondizia cinese o molte altre cose.

C'è un modo semplice per assicurarsi che le impostazioni del terminale (senza hard reset, clean-screen ecc.) Vengano ripristinate quando la shell riprende il controllo?

Lo è bashe Terminal.appimmagino che questo problema sia praticamente universale.

Risposte:


4

I problemi citati sorgono in diversi livelli e solo alcuni di essi possono essere risolti con "codici di escape".

Set di caratteri alternativi nell'emulazione terminale

Esiste un problema terminale comune che potrebbe essere descritto come "(alcune) lettere minuscole vengono visualizzate come simboli o caratteri di disegno al tratto" (vedere questa altra domanda SO ). Questo potrebbe non essere correlato al tuo problema "immondizia cinese", ma è la cosa più vicina che abbia mai visto. È inoltre possibile imbattersi in "immondizia cinese" quando si interpretano quasi tutti i flussi di dati a 8 bit come testo codificato UTF-16. Di solito questo non è un problema "appiccicoso" che deve essere ripristinato, quindi probabilmente non è il problema che stai vedendo.

Il problema "bloccato con caratteri di disegno al tratto" di solito deriva dall'invio all'emulatore di terminale di una sequenza di controllo involontaria (o dall'interruzione di un programma prima che abbia resettato il terminale dopo essere passati al set di caratteri alternativo). Ciò può accadere quando vengono visualizzati alcuni dati binari e il flusso di byte contiene una sequenza di controllo terminale che seleziona un set di caratteri alternativo.

Questo è facile da attivare sulla maggior parte dei terminali in stile VT-100 poiché tutto ciò che serve è un singolo byte (0x0e; vedi la mia risposta alla domanda SO precedentemente collegata ). La sequenza di controllo per ripristinare questa condizione è anche un singolo byte (0x0f; spesso prodotto tramite echo ^V^O(digitato come echo Control+ V Control+ Oo digitato direttamente come printf '\017').

È possibile chiarire questo tipo di problema ** ottenendo la richiesta di includere un byte 0x0f.
** Se la tua "spazzatura cinese" è dovuta a qualche altro problema, potrebbe avere una soluzione diversa.

PS1="\[\017\]… "

I \[e \]sono lì per dire a bash che il carattere limitato è non stampabile. Ciò consente a bash di avere un'idea precisa della posizione "fisica" del cursore (questo è importante per una corretta visualizzazione quando si utilizza la funzionalità di modifica della riga di comando).


Come sottolinea Ignacio Vazquez-Abrams nella sua risposta , un altro modo per ottenere la sequenza di controllo desiderata è tramite il comando tput :

tput rmacs

Usando questo metodo potresti evitare di modificare PS1 e inserire il comando sopra in PROMPT_COMMAND:

PROMPT_COMMAND='tput rmacs'

Opzioni TTY (termios)

Il problema "no echo" *** deriva da impostazioni impreviste delle opzioni per il dispositivo tty basato su sistema operativo che collega l'emulatore di terminale a tutti i programmi eseguiti all'interno della finestra del terminale. Ciò è spesso causato da programmi di interfaccia utente testuali interattivi che presentano bug, arresti anomali o vengono eliminati in modo che non siano in grado di ripristinare tty al suo stato originale.

Puoi controllare queste impostazioni con il comando stty . Questo tipo di problema non può essere risolto con i "codici di escape" poiché le opzioni tty sono configurate tramite API software (vedere tcsetattr (3) e termios (4) ). Generalmente stty saneè un buon meccanismo di ripristino.
*** Anche “no ^ C / ^ Z / ^ /”, “uscita a gradini” (nessun CR automatico quando si riceve un LF) e molti altri problemi.

Ripristina

Il comando reset di solito può aiutare con entrambi i tipi di problemi. Invierà sequenze di controllo di inizializzazione del terminale che di solito risolvono il problema del set di caratteri alternativo e reimposta le opzioni tty su valori ragionevoli.

Il problema con il reset è che stampa anche messaggi extra su alcuni sistemi (es. "Cancella è ...", "Interrompi è ..."); probabilmente non li vuoi visualizzare prima di ogni prompt. Se l'implementazione di reset invia i messaggi e le sequenze di controllo in luoghi diversi (ad esempio, uno va su stdout mentre l'altro va su stderr), allora potresti essere in grado di filtrare i messaggi (ad esempio PROMPT_COMMAND='reset 2>/dev/null'(vedi sotto) e saltare mettendo ^ O in il prompt).

^ O e stty sane

In bash , è possibile impostare il parametro PROMPT_COMMANDsu command e bash verrà eseguito se prima di visualizzare il prompt primario. Puoi inserire tutte le chiamate stty sanee inserire ^ O nel tuo prompt:

PROMPT_COMMAND='stty sane'
PS1="\[\017\]… "

Ancora una volta, potresti evitare di modificare PS1 (e gestire terminali non VT-100) usando tput (come suggerito da Ignacio Vazquez-Abrams):

PROMPT_COMMAND='stty sane; tput rmacs'

Questo deve essere più di un singolo byte, poiché non riesco a riprodurlo per head /dev/urandom- genera immondizia esattamente come previsto, ma poi viene restituito il normale prompt. E ovviamente il terminale è impostato su UTF-8, che si auto-sincronizza. Probabilmente sono alcune sequenze di escape terminali. Esistono modi semplici per testare i problemi comuni e se una particolare soluzione li risolve?
Taw

@taw: sembra che il tuo problema di "immondizia cinese" non sia causato dalla selezione di set di caratteri alternativi. In realtà, il "disegno al tratto anziché le lettere minuscole" è in genere ciò che le persone vedono incuneate in modalità set di caratteri alternativo. Purtroppo non conosco un modo semplice per diagnosticare problemi di emulazione terminale. Potresti provare a catturare alcuni output problematici tramite script(se riesci a riprodurre in modo affidabile la situazione) e isolare la sequenza problematica riproducendo parti dell'output catturato in nuovi terminali (utilizzare una tecnica di ricerca binaria per evitare di dover testare ogni offset di byte).
Chris Johnsen,

@taw: puoi attivare il problema con il set di caratteri alternativo ("altri simboli e disegno al tratto anziché minuscolo") con head /dev/urandom, ma devi prima abilitare il set di caratteri alternativo tramite tput enacs(o la sequenza di controllo multibyte equivalente <ESC> ) 0; questo è decisamente meno probabile di semplice ^ N in un flusso binario casuale). Praticamente qualsiasi istanza di terminale che ha precedentemente eseguito un programma che utilizza caratteri di disegno linea lo avrà già abilitato; quindi, potresti provare head /dev/urandomdopo aver eseguito un programma di disegno al tratto per vedere l'effetto e testare ^ O.
Chris Johnsen,

1

Mettere

echo -n "$(tput rmacs)"

in $PROMPT_COMMAND.


1
tput rmacsè un modo migliore per uscire dalla modalità di set di caratteri alternativo (non è specifico per i terminali in stile VT-100), ma non aiuterà con i problemi di termios. Inoltre, probabilmente non è necessario fare eco al risultato di una sostituzione di comando (basta eseguirlo direttamente; tputè altamente improbabile che la sequenza di controllo emessa da abbia una sua nuova riga).
Chris Johnsen,

0

Quindi sarò meno riga di comando, hai sempre in xterm o in qualsiasi terminale un "pulsante" ripristinato o hard reset, per terminal.app è nel menu Shell. Invia Hard reset alt-command-r.


Bene, l'OP ha detto "senza hard reset" nella domanda.
Chris Johnsen,
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.