It can do with the combination of standard control sequences as follows.
cf. https://ttssh2.osdn.jp/manual/en/about/ctrlseq.html
here is the sample ruby script.
- #!/usr/bin/ruby
- #encoding: ascii-8bit
- require 'io/console'
- resp = ""
- STDIN.raw do |stdin|
- STDERR.print "\e7" # save cursor position
- STDERR.print "\e[999;999H" # move cursor to 999, 999
- STDERR.print "\e[6n" # query cursor position
- STDERR.print "\e8" # restore cursor position
- resp = ""
- while (c = stdin.getc)
- resp << c.chr
- break unless /[\[\x1b\x9c;0-9]/ =~ c
- end
- end
- if /(?:\x9c|\x1b\[)(\d+);(\d+)R/ =~ resp # check response of cursor position query
- rows = $1.to_i
- cols = $2.to_i
- puts "COLUMNS=#{cols}"
- puts "ROWS=#{rows}"
- else
- STDERR.puts "Invalid response"
- end
Another way, using the dtterm's window manipulation sequence.
Here is the sample bash script.
- #!/bin/bash
- die() {
- echo "$@"
- exit 1
- }
- printf "\e[18t"
- read -r -t 1 -n 3 resp
- [ $? -ne 0 ] && die "No response"
- CSI=$(printf "\x9b")
- ESC=$(printf "\e")
- case $resp in
- ${CSI}8\;) : ;;
- ${ESC}\[8)
- read -r -t 1 -n 1 resp
- [ $? -ne 0 -o "$resp" != ";" ] && die "Invalid Response";;
- *) die "Invalid Response";;
- esac
- state=0
- cols=0
- rows=0
- while [ $state -lt 3 ]; do
- read -r -t 1 -n 1 resp
- [ $? -ne 0 ] && die "Invalid Response"
- case $resp in
- [0-9])
- if [ $state -eq 0 ]; then
- rows=$((rows * 10 + resp))
- elif [ $state -eq 1 ]; then
- cols=$((cols * 10 + resp))
- fi;;
- \;) [ $state -lt 2 ] && state=$((++state));;
- t) state=3;;
- *) die "Invalid response";;
- esac
- done
- echo "COLUMNS=$cols"
- echo "ROWS=$rows"
I need to read the terminal height and width (as displayed in the setup menu) from the computer on the serial line.