jendela konsol serial yang dapat diubah ukurannya?

25

Saat menggunakan konsol serial sistem saya, saya selalu berakhir dengan $COLUMNS=80dan $LINES=24.

Walaupun saya dapat mengubah variabel-variabel ini secara manual, agak menjengkelkan untuk melakukan ini kapan saja ketika jendela terminal sisi klien telah diubah ukurannya.

Biasanya saya terhubung ke konsol menggunakan screen /dev/mytty baudrate.

Mengubah $TERMvariabel lingkungan ke "layar" atau "xterm" tidak membantu.

Apakah saya perlu menelepon gettydengan beberapa dari mereka, bukan vt100?

Tidak perlu dikatakan bahwa semua ini berfungsi dengan baik, ketika saya terhubung ke mesin yang sama menggunakan ssh.

Sven Geggus
sumber

Jawaban:

26

Seperti komentator sebelum saya sebutkan, tidak ada alternatif untuk memanggil resizesetelah setiap perintah, jika Anda tidak memiliki perintah ini dan Anda tidak ingin menginstal paket di mana ia berada di ( xterm), berikut adalah dua skrip shell POSIX yang melakukan hal yang sama menggunakan kode pelarian terminal 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"
}

BTW, dalam .profilefile saya, Anda akan menemukan yang berikut: [ $(tty) = /dev/ttyS0 ] && res sehingga ukuran terminal ditentukan pada setiap login melalui jalur serial (yang saya gunakan untuk manajemen), misalnya setelah Anda me-reboot perangkat.
Lihat juga ide oleh rsaw di komentar untuk memiliki garis di [ $(tty) = /dev/ttyS0 ] && trap res2 DEBUGsana sebagai gantinya sehingga mengubah ukuran berjalan setelah setiap perintah (perhatikan bahwa AFAIK itu tidak atau tidak selalu mungkin pada busyboxsekalipun).

phk
sumber
3
PS: Untuk membuat lebih permanen, tambahkan [[ $(tty) == /dev/ttyS0 ]] && trap res2 DEBUGke salah satu konfigurasi profil shell (misalnya /etc/profile,, ~/.bash_profile). Ini akan membuatnya dijalankan setelah setiap perintah tunggal (yang hanya akan menjadi hal yang baik jika Anda mengubah ukuran jendela / panel dengan layar / tmux / terminal-emulator).
rsaw
2
Setelah menggunakannya selama beberapa menit, saya dengan cepat menyadari bahwa keduanya res& res2terlalu lambat untuk apa pun kecuali digunakan pada login pertama. Di mesin saya, mereka berdua mengambil 0,5sec untuk menyelesaikan ... membuat semua perintah saya tampak lamban (bila digunakan dengan perangkap DEBUG). Aduh! Tidak dapat memiliki itu Kira saya akan menginstal xterm.
rsaw
3
@phk xterm's resizeadalah waaaay lebih cepat - biasanya 0,002sec.
rsaw
1
@ Wah Oh, bagus untuk tahu, saya pikir itu akan berperilaku serupa dan karena itu akan sama lambat. Saya ingat bahwa satu di beberapa busyboxes tampaknya lambat bagi saya.
phk
1
Terima kasih atas solusi mandiri ini. Saya menggunakan distro khusus konsol yang tidak menginstal x11 atau xterm jadi resizebukan pilihan.
thom_nic
16

Sebagai catatan, berikut adalah jawaban untuk Masalah ini (Usenet menang):

Aplikasi Konsol yang berjalan di dalam aplikasi terminal virtual ( xterm, rxvtdan teman) akan menerima SIGWINCHsetelah operasi pengubahan ukuran telah terjadi. Dengan demikian aplikasi akan dapat menggambar ulang jendela dll dalam penangan sinyal yang sesuai.

Sayangnya saat menggunakan konsol serial, tidak ada mekanisme seperti itu.

Namun dimungkinkan untuk aplikasi untuk secara aktif meminta ukuran Window konsol saat ini . Jadi, hal terbaik kedua adalah melakukan ini setiap kali prompt perintah dicetak oleh shell.

Ini dapat dicapai dengan terlebih dahulu mengkompilasi ukuran khusus yang dapat dieksekusi dan kemudian menggunakan yang berikut di bashrc:

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

Tentu saja ini tidak akan mengubah pengaturan ukuran konsol dalam aplikasi konsol selama runtime.

Sven Geggus
sumber
1
Bukankah seharusnya mungkin untuk menjalankan protokol di atas garis serial, yang tidak menawarkan semua fitur? Maksudku, kita memang punya klien dan server. Mereka dapat menggunakan urutan pelarian inband untuk melakukan apa saja, dan masih bekerja dengan konsol serial teks biasa!
Evi1M4chine
1
Sebenarnya, komentar dalam kode menjelaskan bahwa bukan versi resizeyang diinstal pada sistem Anda.
Thomas Dickey
9

Terminal "Resizable" adalah hasil dari NAWS ( Negotiate About Window Sizedari RFC 1073 Pilihan Ukuran Jendela Telnet ).

Jika Anda terhubung langsung ke komputer menggunakan port serial, tidak ada negosiasi yang terlibat, dan komputer tidak memiliki pengetahuan langsung tentang ukuran layar terminal Anda.

Jika terminal dapat menegosiasikan ukuran, komputer akan mengirim SIGWINCHke aplikasi yang berjalan di terminal, memberi tahu mereka untuk memperbarui gagasan screensize mereka.

Ketika komputer tidak mengetahui screensize, biasanya mengatur ukuran yang ditunjukkan oleh stty -a(baris dan kolom) menjadi nol. Untuk penggunaan interaktif, ini sedikit tidak ramah, dan beberapa sistem menggunakan variabel lingkungan LINESdan COLUMNSuntuk membantu. Nilai yang diberikan dapat diturunkan dari deskripsi terminal; lebih sering mereka hanya hardcoded. Konvensi untuk variabel-variabel ini mensyaratkan bahwa mereka berlaku kecuali ditekan secara eksplisit, misalnya, dalam use_envfungsi aplikasi kutukan . Di sisi positif, variabel-variabel itu dapat berguna ketika tidak ada informasi yang dapat diandalkan tersedia. Di sisi negatif, tidak ada metode yang mudah untuk mengubah variabel-variabel tersebut.

The resizeProgram (utilitas disediakan dengan xterm) dapat menggunakan VT100 gaya laporan posisi kursor urutan escape untuk menentukan ukuran layar. Ini dapat dijalankan dari baris perintah; tidak ada lagi cara mudah untuk melakukannya secara otomatis. Sebagai efek samping, resizememperbarui informasi pada baris / kolom yang dilihat oleh stty. Penggunaannya untuk menyediakan variabel lingkungan diperbarui terutama berguna untuk kasus-kasus seperti ini, di mana LINESdan COLUMNS yang ditetapkan, dan harus diperbarui.

Thomas Dickey
sumber
3

Berikut adalah solusi lain yang bekerja sangat baik untuk saya pada sistem Linux yang tertanam (Overo menjalankan Angstrom). Saya baru saja menjalankannya dari file .bashrc saya. Saya tidak ingin menggunakan pengubahan ukuran karena itu perlu menginstal beberapa paket X, dan saya tidak menginginkannya.

Memberitahu Raspberry Pi Anda bahwa terminal Anda lebih besar dari 24 baris | Blog Pikiran Dangkal

Austin Beer
sumber
3
Tolong jangan hanya mengirim tautan: sertakan detail yang relevan sehingga informasinya juga tersedia di sini ...
jasonwryan
1
Sayang sekali perlu Python.
Craig McQueen
1

Jika Anda dapat menggunakan FreeBSD sebagai gantinya, ada perintah resizewin (1) , yang melakukan persis apa yang Anda inginkan.

Edward Tomasz Napierala
sumber
1

Saat menjalankan sesi shell melalui jalur serial, cukup memanggil resizeperintah di dalam sesi itu - setelah membuat koneksi dan setelah setiap perubahan geometri terminal.

The resizePerintah merupakan bagian dari xterm tetapi tidak tergantung pada X11. Misalnya, pada Fedora itu secara terpisah dikemas sebagai xterm-resize.

Bagaimana cara kerjanya: perintah resize mengukur tinggi / lebar melalui beberapa gerakan kursor dan kemudian mengirimkan nilai-nilai tersebut ke terminal melalui escape sequence.

Dengan shell seperti zsh, ini juga secara otomatis memperbarui LINESdan COLUMNSvariabel (sebagai alternatif, seseorang dapat mengevaluasi pernyataan ekspor yang dicetak perintah ke stdout).

Mengapa ini perlu: dengan sesi lokal atau ssh terminal dapat memberi sinyal sesi tentang perubahan geometri (lih. SIGWINCH). Mekanisme ini tidak berfungsi melalui koneksi serial.

maxschlepzig
sumber
0

Berikut adalah fungsi pengubahan ukuran sederhana dan cepat yang hanya berfungsi untuk bash. Itu dimodifikasi dari res2 phk, memanfaatkan bash read -d delimuntuk menghindari membiarkan batas waktu selesai membaca.

resize() {
  old=$(stty -g)
  stty -echo
  printf '\033[18t'
  IFS=';' read -d t _ rows cols _
  stty "$old"
  stty cols "$cols" rows "$rows"
}
Gary Guo
sumber