获取 termcap 功能的终端状态

获取 termcap 功能的终端状态

如何检索终端设置的状态,例如smamrmam

原因是我设置rmam的:

tput rmam

在脚本中,然后继续设置smam退出:

tput smam

但如果rmam脚本启动时终端已设置,我不想smam在退出时设置。


如何才能做到这一点?

答案1

在支持它的终端模拟器上,您可以使用\033[?7$p转义(“请求 DEC 私有模式”)来查询该参数(7=> 自动换行模式):

decrqm()(
    exec </dev/tty
    t=$(stty -g)
    trap 'stty "$t"; return' EXIT QUIT INT TERM
    stty -icanon -echo time 1 min 0
    e=$(printf '\033')
    printf "${e}[$1\$p" >/dev/tty
    case $(dd count=1 2>/dev/null) in
    "${e}[$1;1\$y") echo on;;
    "${e}[$1;2\$y") echo off;;
    *) echo unknown;;
    esac
)

$ tput smam  # printf '\033[?7h'
$ decrqm '?7'
on
$ tput rmam  # printf '\033[?7l'
$ decrqm '?7'
off

更好的方法是节省\033[?7s使用和启动脚本时的设置恢复退出时\033[?7r

save_am(){ printf '\033[?7s'; }
restore_am(){ printf '\033[?7r'; }

save_am
tput rmam
..
restore_am

但许多终端模拟器(特别是screentmux不支持那些逃脱。至少默认情况下不是。所以这一切都是纯粹的琐事——你不能用它来做任何实际的事情;-)

答案2

极其丑陋,但可以检测到:

#!/bin/bash

# Detect smam / rmam by printing COLUMNS characters and 
# checking cursor line before and after.

smam()
(
    local -i smam r1 r2 cw
    exec </dev/tty
    local t=$(stty -g)
    trap 'stty "$t"; return' EXIT QUIT INT TERM
    stty -icanon -echo time 1 min 0

    # Terminal width + 1
    (( cw = $(tput cols) + 1 ))

    # Create a blank line and go back up (in case we are at bottom)
    printf "\n"
    tput cuu1
    # Get cursor row 1
    printf "\x1b[6n" >/dev/tty
    r1=$(dd count=1 2>/dev/null | sed 's/\x1b\[\(.*\);.*/\1/')
    # Print columns + 1 spaces
    for ((i = 0; i < cw; ++i)); do printf " "; done
    # Get cursor row 2 AND go to start of line
    printf "\x1b[6n\r" >/dev/tty
    r2=$(dd count=1 2>/dev/null | sed 's/\x1b\[\(.*\);.*/\1/')

    # smam is true if we are at a higher line number
    (( smam = r2 - r1 ))
    # Clear line
    tput el
    # If smam clear line we started on as well
    (( smam )) && tput cuu1 && tput el
    # Optional debug check 
    # printf "%d %d\n" $x1 $x2
    return $(( smam ^ 1 ))
)

# example:

smam && echo smam || echo rmam


一个怪癖是,人们必须随时待命地拨打新线路。

相关内容