4

QEMU was leaving my terminal in a weird state and it took me a while to finally debug it to the precise capability in question: tput smam vs tput rmam.

Is there a way to inspect the current terminal state, hopefully showing the current value of all capabilities at once?

This would allow me to easily diff out a working vs a "broken" terminal to find out what was modified.

Finding out the current state of any specific capability would also be a good start though, e.g. smam vs rmam.

Tested in Ubuntu 19.10, Gnome terminal.

3 Answers 3

5

This might work (VTE implements part of this control):

CSI ? Ps $ p

Request DEC private mode (DECRQM). For VT300 and up, reply DECRPM is

CSI ? Ps ; Pm $ y

where Ps is the mode number as in DECSET/DECSET, Pm is the mode value as in the ANSI DECRQM.

specifically, Ps is 7:

       Ps = 7  ⇒  Auto-wrap Mode (DECAWM), VT100.

which corresponds to the settings used in the terminal description:

rmam=\E[?7l, smam=\E[?7h,

so... you'd do

printf '\033[?7$p'

and expect to get back

\033[?7;1$y

or

\033[?7;2$y

depending on whether the mode was set or reset, respectively.

This also assumes your script/program is reading from the terminal (not necessarily standard input). There are several test/demo scripts in xterm's sources which you might find useful reading (though most will not work with VTE). Generally I'd test this feature with vttest, which has been packaged for whatever system you're using.

5
  • Thanks for this suggestion Thomas, but I'm afraid it didn't seem to work on my system: printf '\033[?7$p' | hd produces 1b 5b 3f 37 24 70 |.[?7$p| both after tput smam and tput rmam. Commented Dec 24, 2019 at 14:16
  • Perhaps you're not reading from the terminal - I added a clarification. But piping through hd doesn't sound as if you're writing to the terminal. Commented Dec 24, 2019 at 14:19
  • Given the | hd the easier conclusion is that xe is not writing to the terminal. (-:
    – JdeBP
    Commented Dec 24, 2019 at 14:33
  • 2
    @Ciro if you want hd, do it like this: (g=$(stty -g); stty -icanon -echo min 0 time 5; printf '\033[?7$p'; dd count=1 2>/dev/null | hexdump -C; stty "$g"). That escape doesn't work in screen or tmux.
    – user313992
    Commented Dec 25, 2019 at 2:37
  • @mosvy ah, actually yes, it works without | hd. I thought I had tried that yesterday, oh well. But good to know how to obtain it programatically as you showed, since the end goal would be to generate a human readable list of all properties in one go. Commented Dec 25, 2019 at 8:04
3

To complement Thomas Dickey's helpful answer, which provides all crucial information with POSIX-compliant convenience function tmode, adapted from the helpful command in mosvy's comment:

Given a terminal mode number, it prints 'SET' or 'RESET' to reflect the mode's status; e.g.:

# Get status of the DECAWM (autowrap) mode
$ tmode 7
RESET

CAVEATS:

If anyone can shed more light on these, please comment.

  • The function works only in certain terminal emulators, notably not in Gnome Terminal:

    • macOS: iTerm2.app, but not the built-in Terminal.app
    • Ubuntu: XTerm and UXTerm, but not the standard Gnome Terminal
    • Windows (WSL): not supported; neither in a legacy console window nor in Windows Terminal.
  • Re supported mode numbers :

    • The console_codes(4) Linux man page in section "DEC Private Mode (DECSET/DECRST) sequences" mentions only 1, 3, 5..9, 25 and 1000

    • In practice, the terminal emulates mentioned above return meaningful values for the following:

      • iTerm2.app on macOS: 1..3, 5..8, 25, 40..41, 45, 47, 69, 1000
      • [U]XTerm on Ubuntu: 1..7, 9, 12, 18..19, 25, 30, 35, 38, 40..42, 44..45, 47, 66..67, 69, 80, 95, 1000
    • There are other, non-numeric modes mentioned in the linked man page, such as = (DECPAM) and > (DECPNM) - I don't know how to query those.

    • While Thomas Dickey's link to the explanation of the DEC private-mode escape sequences mentions return value 0 as indicating an unknown mode and 3 / 4 as "permanently set/reset"; in practice it seems to be 4 that indicates a unknown mode, with known modes only ever reporting 1 ("set", i.e. on) or 2 ("reset", i.e. off).

Shell function tmode:

#! /bin/sh -

tmode() (

  [ "$#" -eq 1 ] || { echo "Usage: tmode <mode-number>" >&2; return 2; }
  modeNum="$1"

  # Redirect stdin and stdout temporarily to the controlling terminal.
  # This is necessary so that invocation such as `result=$(tmode 1)` work.
  {
    stty_settings="$(stty -g)"
    stty -icanon -echo min 0 time 5
    # Query the terminal.
    printf '\33[?%s$p' "$modeNum"
    result=$(dd count=1)
    stty "$stty_settings"
  } <> /dev/tty >&0 2> /dev/null
  
  # Activate this to visiualize the raw result.
  # printf %s "$result" | od -t x1 -t c > /dev/tty

  # Print a friendly result.
  case $result in
    *';1$'*)
     echo SET;;
    *';2$'*)
     echo RESET;; 
    # NOTE: It seems that 4 is only ever used to signal a nonexistent mode.
    # *';3$'*)
    #  echo PERMANENTLY SET;; 
    # *';4$'*)
    #  echo PERMANENTLY RESET;; 
    *)
      echo "Unknown mode: $modeNum" >&2;;
  esac
)
0

set mode

ESC [ Ⓝ h
ESC [ ? Ⓝ h

reset mode //unset

ESC [ Ⓝ l
ESC [ ? Ⓝ l

request mode //query state

ESC [ Ⓝ $ p
ESC [ ? Ⓝ $ p

Ⓝ is a decimal number (the mode number)

test in shell

#set
echo -ne '\e[?1049h'

#query = set
echo -ne '\e[?1049$p'; cat
^[[?1049;1$y

#reset
echo -ne '\e[?1049l'

#query = not set
echo -ne '\e[?1049$p'; cat
^[[?1049;2$y

refs

xterm docs: DECRQM DECRQM
https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#:~:text=DECRQM
NOTE: use chrome access can scroll to highlight keyword in webpage


control sequences
https://terminalguide.namepad.de/seq/

mode list
https://terminalguide.namepad.de/mode/

set mode
https://terminalguide.namepad.de/seq/csi_sh/
https://terminalguide.namepad.de/seq/csi_sh__p/

request mode
https://terminalguide.namepad.de/seq/csi_sp_t_dollar/
https://terminalguide.namepad.de/seq/csi_sp__p_t_dollar/


vt100 docs
https://vt100.net/docs/vt510-rm/DECRQM.html
https://vt100.net/docs/vt510-rm/DECRPM.html
https://vt100.net/docs/vt220-rm/chapter4.html#S4.6

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .