4

虽然我知道tput rmcup从“备用屏幕”(在 中称为“杯子模式” man 5 terminfo)返回并恢复保存的屏幕,但它确实具有重新定位光标的副作用。

因此,如果tput smcup被调用,则tput rmcup恢复屏幕并重新定位光标,但如果您随后键入更多命令或按回车键几次然后tput rmcup再次使用,则光标将返回到原始保存的位置。

一个用例是在bash[使用scriptreplay] 回放终端记录的脚本中:如果脚本在没有 [相当于] 调用的情况下提前结束,tput rmcup那么我希望能够在我的bash脚本中检测到它并tput rmcup自动调用。

简而言之,我希望能够确定当前的屏幕状态是什么;即,它是“备用屏幕”还是“正常屏幕”?

4

1 回答 1

3

如果您使用的是 xterm,那么您可以询问它使用的是什么模式。尽管备用屏幕功能是 xterm 功能而不是“DEC”,但该设置与XTerm 控制序列DECSET中描述的模式组合在一起:

CSI ? Pm h
          DEC Private Mode Set (DECSET).
...
            Ps = 1 0 4 7  -> Use Alternate Screen Buffer, xterm.  This
          may be disabled by the titeInhibit resource.
            Ps = 1 0 4 8  -> Save cursor as in DECSC, xterm.  This may
          be disabled by the titeInhibit resource.
            Ps = 1 0 4 9  -> Save cursor as in DECSC, xterm.  After sav-
          ing the cursor, switch to the Alternate Screen Buffer, clear-
          ing it first.  This may be disabled by the titeInhibit

DECRQM控件可用于查询终端:

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.

也就是说,您的脚本可以

printf '\033[?1049$p'

并读回结果,期待类似的东西\033[?1049;1$y

这是一个快速演示:

#!/bin/sh                                                                      

unexpected() {
        result=$(echo "$check"|sed -e 's/^@/\\033/')
        printf '? unexpected reply: %s\n' "$result"
        exit 1
}

exec </dev/tty
old=`stty -g`
stty raw -echo min 0  time 5
printf '\033[?1049$p'
read status
stty $old

if [ -n "$status" ]
then
        check=$(echo "$status" |tr '\033' '@')
        if [ "$check" != "$status" ]
        then
                case "$check" in
                '@[?1049;1$y')
                        echo "alternate screen"
                        ;;
                '@[?1049;2$y')
                        echo "normal screen"
                        ;;
                *)
                        unexpected
                        ;;
                esac
        else
                unexpected
        fi
else
        echo "? no reply from terminal"
fi

当然,如果您不使用 xterm,您的里程可能会有所不同......

于 2018-04-18T23:03:26.330 回答