我编写了以下脚本,以便在每次更改时打印出当前行和行,也就是每次我按向上、向下、向左或向右时,但输出始终相同:
row:43:col:141
我相信这意味着屏幕的左上角,其中 0 0 位于右下角,但我不太确定。
这是我的脚本:
#!/bin/bash
echo "press a key"
tput clear
row=$(tput lines)
col=$(tput cols)
while true; do
echo "row:$row:col:$col"
K1=,K2=,K3=
read -s -N1
K1="$REPLY"
read -s -N1 -t 0.001
K2="$REPLY"
read -s -N1 -t 0.001
K3="$REPLY"
key="$K1$K2$K3"
case "$key" in
$'\033[A') tput cuu 1;;
$'\033[B') tput cud 1;;
$'\033[C') tput cuf 1;;
$'\033[D') tput cup $row $(($col-1));;
*) echo "pressed a key!";;
esac
row=$(tput lines)
col=$(tput cols)
done
exit 0
显然没有办法使用 tput 将光标向左移动,所以我使用了:
tput cup $row $(($col-1))
但这也不起作用,有什么想法如何解决吗?
tput lines
并tput cols
以字符为单位返回窗口的当前大小。如果拖动窗口来更改其大小,您(通常)会看到新值以交互方式更改。它们与光标位置无关。另外,窗口的左上角是(0,0)。您的右下角当前为 (42,140),因为仓位是从零开始的。
tput cub1
应该向左移动。所有cub1
,cuf1
,cuu1
,cud1
都是单个单词 - 没有空格。没有 cub2 等。此外,tput cud1
将光标移动到下面一行的第一列:tput cuu1
停留在上面一行的同一列。(不过,这可能是我的配置中的一个错误。)我认为没有 tput 选项来读取光标位置。程序员有责任跟踪它的结束位置,或者将光标移动到下一个文本输出应该放置的位置。您可以使用 保存一个位置
tput sc
,并使用 恢复该位置(可能多次)tput rc
。cursor_address (cup)、column_address (hpa) 和 row_address (vpa) 采用绝对行号和列号(从零开始),比单字符移动更有用。
完整的终端命令集应记录在 中
man -s 5 terminfo
,但tput
它是一个相当笨重的工具(每个命令都有一个新过程),因此ncurses
(或至少C
)任何严肃的工作都需要它。这是我对这些在我的
TERM=xterm-256color
.编辑:
tput
您可以通过对您希望使用的每个序列询问一次并使用重复的函数来优化代码。这样就可以避免调用这么多的外部进程,并且使代码更简单、更具可读性。下面的代码说明了这些优化。有相当多的一次性代码来获取 tput 序列并定义实用函数。之后,实际的展示工作是简短、高效且具有相当可读性的。
进程替换在这些序列上效果不佳:例如,它删除换行符。下面的方法(阅读,拒绝所有分隔符)是稳健的。
X
此代码说明了如何使用光标键在屏幕上移动。屏幕尺寸为
0 ≤ row < rows
和0 ≤ col < cols
。使用光标键移动、Esc退出。修改左/右操作的代码来处理环绕并不困难。让打印字符以文字处理器的方式写入屏幕也不是非常困难。