如何检索终端设置的状态,例如smam
和rmam
?
原因是我设置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
但许多终端模拟器(特别是screen
和tmux
)不支持那些逃脱。至少默认情况下不是。所以这一切都是纯粹的琐事——你不能用它来做任何实际的事情;-)
答案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
一个怪癖是,人们必须随时待命地拨打新线路。