finestra della console seriale ridimensionabile?


25

Quando utilizzo la console seriale del mio sistema, finisco sempre con $COLUMNS=80e $LINES=24.

Mentre posso cambiare queste variabili manualmente, è un po 'fastidioso farlo in qualsiasi momento quando la finestra del terminale lato client è stata ridimensionata.

Di solito mi connetto alla console usando screen /dev/mytty baudrate.

La modifica della $TERMvariabile di ambiente in "schermo" o "xterm" non aiuta.

Dovrò chiamare gettycon alcuni di quelli invece di vt100?

Inutile dire che tutto questo funziona bene, quando mi collego alla stessa macchina usando ssh.

Risposte:


26

Come i commentatori prima di me menzionati, non c'è alternativa alla chiamata resizedopo ogni comando, se non si dispone di questo comando e non si desidera installare un pacchetto in cui si trova ( xterm), ecco due script di shell POSIX che fanno lo stesso utilizzando i codici di escape del terminale ANSI:

res() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\0337\033[r\033[999;999H\033[6n\0338' > /dev/tty
  IFS='[;R' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

res2() {

  old=$(stty -g)
  stty raw -echo min 0 time 5

  printf '\033[18t' > /dev/tty
  IFS=';t' read -r _ rows cols _ < /dev/tty

  stty "$old"

  # echo "cols:$cols"
  # echo "rows:$rows"
  stty cols "$cols" rows "$rows"
}

A proposito, nel mio .profilefile troverai quanto segue: in [ $(tty) = /dev/ttyS0 ] && res modo che la dimensione del terminale sia determinata ad ogni accesso sulla linea seriale (quello che uso per la gestione), ad esempio dopo aver riavviato il dispositivo.
Vedi anche l'idea di rsaw nei commenti di avere la linea [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGlì, quindi il ridimensionamento viene eseguito dopo ogni comando (nota che AFAIK non è o non è sempre possibile su busybox).


3
PS: Per rendere più stabile, aggiungere [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGad una delle configurazioni di profilo shell (ad esempio, /etc/profile, ~/.bash_profile). Questo lo farà funzionare dopo ogni singolo comando (il che sarebbe positivo solo se ridimensionate windows / riquadri con screen / tmux / terminal-emulator).
rsaw,

2
Dopo averlo usato per un paio di minuti ho capito subito che sia rese res2sono troppo lento per tutto tranne l'uso su primo login. Sulle mie macchine, impiegano entrambi 0,5 secondi per finire ... facendo sembrare lenti tutti i miei comandi (se usati con la trappola DEBUG). Ops! Non posso averlo. Immagino che installerò xterm.
rsaw,

3
@phk xterm's resizeè waaaay più veloce - di solito 0,002sec.
rsaw,

1
@rsaw Oh OK, buono a sapersi, ho pensato che si sarebbe comportato in modo simile e quindi allo stesso modo lento. Ricordo che quello in alcuni busyboxsembrava essere altrettanto lento per me.
phk,

1
Grazie per questa soluzione autonoma. Sto usando una distribuzione solo console che non ha x11 o xterm installati, quindi resizenon è un'opzione.
thom_nic

16

Per la cronaca, ecco la risposta a questo problema (Usenet ha vinto):

Le applicazioni in esecuzione all'interno della console applicazioni terminali virtuali ( xterm, rxvte amici) riceveranno SIGWINCHdopo un'operazione di ridimensionamento ha avuto luogo. In questo modo l'applicazione sarà in grado di ridisegnare la finestra ecc. Nel gestore del segnale corrispondente.

Sfortunatamente quando si utilizza una console seriale, non esiste un tale meccanismo.

È comunque possibile che l'applicazione richieda attivamente le dimensioni della finestra della console corrente . Quindi la seconda cosa migliore è farlo ogni volta che un prompt dei comandi viene stampato dalla shell.

Ciò può essere ottenuto compilando prima un eseguibile di ridimensionamento speciale e quindi utilizzando quanto segue in bashrc:

if [ $(tty) == '/dev/ttyS0' ]; then
  trap resize DEBUG
fi

Naturalmente ciò non modificherà le impostazioni della dimensione della console in un'applicazione console durante il runtime.


1
Non dovrebbe essere possibile eseguire un protocollo sulla linea seriale, che non offrono tutte le caratteristiche? Voglio dire, abbiamo un client e un server. Potrebbero usare sequenze di escape in-band per fare praticamente tutto e continuare a lavorare con una console seriale in testo normale!
Evi1M4chine,

1
In realtà, il commento nel codice chiarisce che non è la versione di resizecui è installata sul tuo sistema.
Thomas Dickey,

9

I terminali "ridimensionabili" in quanto tali sono il risultato di NAWS ( Negotiate About Window Sizeda RFC 1073 Telnet Window Size Opzione ).

Se si è collegati direttamente al computer tramite una porta seriale, non è prevista alcuna negoziazione e il computer non è a conoscenza diretta delle dimensioni dello schermo del terminale.

Se un terminale può negoziare la dimensione, il computer invierà SIGWINCH alle applicazioni in esecuzione nel terminale, dicendo loro di aggiornare la loro nozione di dimensione dello schermo.

Quando il computer non conosce la dimensione dello schermo, in genere imposta la dimensione mostrata da stty -a(righe e colonne) su zero. Per un uso interattivo, questo è un po 'ostile e alcuni sistemi usano variabili d'ambiente LINESe COLUMNSper aiutare. I valori assegnati possono essere derivati ​​dalla descrizione del terminale; più spesso sono semplicemente codificati. La convenzione per queste variabili richiede che abbiano effetto a meno che non vengano esplicitamente soppresse, ad esempio, nelle applicazioni maledizioniuse_env funzione delle . Sul lato positivo, queste variabili possono essere utili quando non sono disponibili informazioni affidabili. Sul lato negativo, non esiste un metodo conveniente per modificare tali variabili.

Il resizeprogramma (un'utilità fornita con xterm) può utilizzare la sequenza di escape del rapporto sulla posizione del cursore in stile VT100 per determinare la dimensione dello schermo. Questo può essere eseguito dalla riga di comando; non c'è (di nuovo) un modo conveniente per farlo automaticamente. Come effetto collaterale, resizeaggiorna le informazioni sulle righe / colonne visualizzate da stty. Il suo utilizzo per fornire variabili di ambiente aggiornate è utile soprattutto in casi come questo, dove LINESe dove COLUMNS sono impostati, e dovrebbe essere aggiornato.


3

Ecco un'altra soluzione che ha funzionato perfettamente per me sul mio sistema Linux incorporato (Overo con Angstrom). L'ho appena eseguito dal mio file .bashrc. Non volevo usare il ridimensionamento perché questo richiede l'installazione di alcuni pacchetti X, e non lo volevo.

Dire al tuo Raspberry Pi che il tuo terminale è più grande di 24 linee | Blog di pensieri superficiali


3
Per favore, non solo pubblicare un link: includi i dettagli pertinenti in modo che le informazioni siano disponibili anche qui ...
Jasonwryan,

1
Peccato che abbia bisogno di Python.
Craig McQueen,


1

Quando si esegue una sessione di shell su una linea seriale è sufficiente chiamare il resize comando all'interno di quella sessione - dopo aver stabilito la connessione e dopo ogni modifica della geometria del terminale.

Il resizecomando fa parte di xterm ma non dipende da X11. Ad esempio, su Fedora è confezionato separatamente come xterm-resize.

Come funziona: il comando di ridimensionamento misura l'altezza / larghezza tramite alcuni movimenti del cursore e quindi invia tali valori al terminale tramite sequenze di escape.

Con una shell come zsh, questo aggiorna anche automaticamente le variabili LINESe COLUMNS(in alternativa, si possono valutare le istruzioni di esportazione che i comandi stampano su stdout).

Perché questo è necessario: con una sessione locale o ssh il terminale è in grado di segnalare la sessione sui cambiamenti della geometria (vedi SIGWINCH). Questo meccanismo non funziona su una connessione seriale.


0

Ecco una funzione di ridimensionamento semplice e veloce che funziona solo per bash. Viene modificato dalla res2 di phk, usando bash read -d delimper evitare che il timeout finisca la lettura.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
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.