Linux bash:获取终端光标位置后的奇怪行为



我写了一个shell脚本来收集和显示成功登录后的一些信息。 但是,有些信息需要一些时间来收集,所以我在返回并将延迟信息打印到正确的位置之前,我会提前打印一些标题和已经可用的信息。

为此,我使用以下脚本来获取当前光标位置(忽略之前所有无聊的内容。这是一堆印刷品,猫和切...

. ...
. ...
printf "^[[0m""n"
# Get current settings.
if ! termios="$(stty -g 2>/dev/null)" ; then
echo "Not running in a terminal." >&2
exit 1
fi
# Restore terminal settings when the script exits.
trap "stty '$termios'" EXIT
# Disable ICANON ECHO. Should probably also disable CREAD.
stty -icanon -echo
# Request cursor coordinates
printf '33[6n'
# Read response from standard input; note, it ends at R, not at newline
read -d "R" rowscols
# Clean up the rowscols (from 33[rows;cols -- the R at end was eaten)
rowscols="${rowscols//[^0-9;]/}"
rowscols=("${rowscols//;/ }")
#printf '(row %d, column %d)n' ${rowscols[0]} ${rowscols[1]}    *<-- commented by me*
# Reset original terminal settings.
stty "$termios"
# To the stuff...
printf '(row %d, column %d)n' ${rowscols[0]} ${rowscols[1]}
line=${rowscols[0]}
line=$(($line - 10))                        *<--- Indeed script's line 102. I want subtract 10*
col=56
printf '(r= %d, c= %d)n' ${line} ${col}    *<--- Printed two times, both times wrong values*
exit 1      *<--- Put here just to exit earlier*

## Get uptime/activetime formated to my taste.
m_activetime=$(/usr/bin/activetime -v)
printf "33[%d;%dH^[[38;5;196m ${m_activetime}" ${line} ${col}
. ...
. ...

当我运行代码时,我得到:

. ...
. ...
. ...
||=-= _ |-=-   |+++++++| _    ||= _   |            :
`~‾‾ '--~~__|- =   |+++++__|----~‾  ‾~`---',  CPU stat⸱:
~---__|,--~'                     Weather⸱⸱:
(row 16, column 1)
./c.asc: line 102: 16 1 - 10: syntax error in expression (error token is "1 - 10")
(r= 16, c= 1)
(r= 56, c= 0)
lr@pi:~ $

1(脚本是bash(shebang#!/usr/bash(

2(线条(row 16, column 1)似乎还可以!

3(脚本称为c.asc

4(我想知道这个错误到底是什么,我以前使用过类似的表达式,不是 bash 数组,但即便如此......

line 102: 16 1 - 10: syntax error我可以猜到16,但它是哪来的1 - 10

(error token is "1 - 10")什么标记"1 - 10"????!!!

5(第一个(r= 16, c= 1)已经错了,应该(r= 6, c= 56)。这是为什么呢?10的减法怎么了?变量的值去哪儿了?

6(更奇怪。我没有指示第二次打印,即便如此,现在变量存在身份危机并显示col值,并且在这两种情况下,指令 col=56 似乎都被忽略了。变量线为什么以及如何获得变量的值?为什么变量col从错误的值 1 移动到错误的值 0?

7(显示的脚本已转换以跟踪错误。它从未打印到预期位置开始,并显示错误。此外,printf 的一个版本printf '(r= %d, c= %d)n' $((${line} - 10)) ${col}显示同样相似和奇怪的错误。


附言

经过一些额外的实验,仅使用脚本的一部分来获取终端光标位置,似乎也不完全理智。它返回位置正常,但尝试像read r c < <(curspos)这样的事情(假设curspos是返回元组lin col的脚本的名称(,提示挂起,直到按下 Ctrl-C 并在该提示之后变得疯狂。

谢谢

问题是你引用了数组的值。

rowscols=("${rowscols//;/ }")

这告诉 bash 忽略空格并将其视为一个值。因此,当您稍后获得第一个值${rowscols[0]}时,您实际上会得到16 1而不是16并且没有第二个值。

它也适用于这个 printf,因为你没有引用那里的值。

printf '(row %d, column %d)n' ${rowscols[0]} ${rowscols[1]}

我不知道为什么它运行了两次最后一个 printf,但它似乎可以通过引用来解决。

最新更新