Linux bash: 获取终端光标位置后的奇怪行为
Linux bash: strange behavior after getting terminal cursor position
我写了一个 shell 脚本来收集并在成功登录后显示一些信息。
然而,一些信息需要一些时间来收集,所以我提前打印到终端(ssh putty)一些 headers 和已经可用的信息,然后返回并将延迟的信息打印到正确的位置。
为了实现这一点,我使用了以下脚本来获取当前光标位置,(忽略之前所有无聊的东西。它是一堆 printf、cat 和 cut 的...
. ...
. ...
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 '3[6n'
# Read response from standard input; note, it ends at R, not at newline
read -d "R" rowscols
# Clean up the rowscols (from 3[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 "[%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 是怎么回事?变量 col 的值去哪儿了?
6) 更奇怪。我没有指示第二次打印,即使如此,现在变量 line 出现身份危机并显示 col 值,并且在在这两种情况下,指令 col=56 似乎都被忽略了。变量 line 为什么以及如何得到变量 col 的值?为什么变量 col 从错误值 1 变为错误值 0?
7) 显示的脚本已转换为跟踪错误。它开始时未打印到预期位置,并显示错误。还有一个版本的 printf printf '(r= %d, c= %d)\n' $((${line} - 10)) ${col}
显示同样相似和奇怪的错误。
p.s.
经过一些额外的实验,仅使用脚本的一部分来获取终端光标位置,它似乎也不完全正常。它 return 的位置没问题,但尝试像 read r c < <(curspos)
这样的事情(假设 curspos 是 return 元组 lin col
),提示挂起,直到按下 Ctrl-C,然后提示变得疯狂。
谢谢
问题是您引用了数组的值。
rowscols=("${rowscols//;/ }")
这告诉 bash 忽略空格并将其视为一个值。因此,当您稍后使用 ${rowscols[0]}
获得第一个值时,您实际上得到的是 16 1
而不是 16
并且没有第二个值。
它也适用于此 printf,因为您没有在此处引用值。
printf '(row %d, column %d)\n' ${rowscols[0]} ${rowscols[1]}
不知道为什么运行最后一次printf两次,不过好像用引号解决了
我写了一个 shell 脚本来收集并在成功登录后显示一些信息。 然而,一些信息需要一些时间来收集,所以我提前打印到终端(ssh putty)一些 headers 和已经可用的信息,然后返回并将延迟的信息打印到正确的位置。
为了实现这一点,我使用了以下脚本来获取当前光标位置,(忽略之前所有无聊的东西。它是一堆 printf、cat 和 cut 的...
. ...
. ...
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 '3[6n'
# Read response from standard input; note, it ends at R, not at newline
read -d "R" rowscols
# Clean up the rowscols (from 3[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 "[%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 是怎么回事?变量 col 的值去哪儿了?
6) 更奇怪。我没有指示第二次打印,即使如此,现在变量 line 出现身份危机并显示 col 值,并且在在这两种情况下,指令 col=56 似乎都被忽略了。变量 line 为什么以及如何得到变量 col 的值?为什么变量 col 从错误值 1 变为错误值 0?
7) 显示的脚本已转换为跟踪错误。它开始时未打印到预期位置,并显示错误。还有一个版本的 printf printf '(r= %d, c= %d)\n' $((${line} - 10)) ${col}
显示同样相似和奇怪的错误。
p.s.
经过一些额外的实验,仅使用脚本的一部分来获取终端光标位置,它似乎也不完全正常。它 return 的位置没问题,但尝试像 read r c < <(curspos)
这样的事情(假设 curspos 是 return 元组 lin col
),提示挂起,直到按下 Ctrl-C,然后提示变得疯狂。
谢谢
问题是您引用了数组的值。
rowscols=("${rowscols//;/ }")
这告诉 bash 忽略空格并将其视为一个值。因此,当您稍后使用 ${rowscols[0]}
获得第一个值时,您实际上得到的是 16 1
而不是 16
并且没有第二个值。
它也适用于此 printf,因为您没有在此处引用值。
printf '(row %d, column %d)\n' ${rowscols[0]} ${rowscols[1]}
不知道为什么运行最后一次printf两次,不过好像用引号解决了