在一個臆造的例子中,如果我有以下內容:
sup="$(printf "e[s"/span>> /dev/tty; printf "one" > /dev/tty; printf "e[ue[Jtwo" > /dev/tty) "
輸出將成功擦除一個,只留下:
two
但是,如果我使用echo "one"來列印一個換行符的話:
sup="$(printf "e[s"/span> > /dev/tty; echo "one" > /dev/tty; printf "e[ue[Jtwo" > /dev/tty) "
然后輸出結果是:
一
二
為什么換行會破壞游標處理?我怎樣才能解決這個問題呢?
一個更全面的例子是:
sup="$(printf "e[s"/span> > /dev/tty; for ( ( i=0; i<5; i )); do echo -e "一個亂數是。
$RANDOM" > /dev/tty; sleep 1; printf "e[ue[J" > /dev/tty; done; echo 'result')"
echo "sup=$sup"/span> # sup=result
uj5u.com熱心網友回復:
我懷疑你在向視窗的最后一行寫東西。寫一個換行會導致視窗內容滾動。當你用ESC [ u恢復游標位置時,它回傳到用ESC [ s保存的視窗中的物理位置,而不是滾動緩沖區中的位置。但是one這個詞已經向上滾動了一行,所以two將被寫到它后面的一行,而不是覆寫它。
uj5u.com熱心網友回復:
正如@Barmer的答案所暗示的,恢復游標不起作用的原因是,保存游標只保存左/右邊距,而不是保存行:
在SCO控制臺模式下,保存游標的位置/狀態。[22] 在垂直分屏模式下,而是用來設定(如CSI n ; n s)或重置左右邊距。 https://en.wikipedia.org/wiki/ANSI_escape_code#CUP
我能夠想出一個便攜的解決方案,不需要我計算行數。
tty.bash
#!/usr/bin/env bash
# sourced from:
# https://stackoverflow.com/a/69138082/130638
# inspired by:
# https://unix.stackexchange.com/a/88304/50703
# https://stackoverflow.com/a/2575525/130638
# https://askubuntu.com/a/366158/22776
# https://stackoverflow.com/a/5810220/130638
get_tty_snapshot(){
local pos oldstty y x y_offset="${1: -0}" x_offset="${2:-0}"/span>
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
echo -en "e[6n"/span> > /dev/tty
IFS=';' read -r -d R -a pos
stty "$oldstty"
y="$((${pos[0]:2}-2 y_offset))"
x="$((pos[1] - 1 x_offset)/span>)"
echo -en "e[${y}; ${x}He[J"
}
use_tty_snapshot ( ) {
echo -en "$1"/span> > /dev/tty
}
embed.bash
#!/usr/bin/env bash
source "./tty.bash"
tty_snapshot="$(get_tty_snapshot)"
for ( ( i=0; i<5; i )); do
echo -e "一個亂數$RANDOM。
另一個亂數。$RANDOM" > /dev/tty
睡眠1
use_tty_snapshot "$tty_snapshot"。
done
echo 'result'/span>
example.bash
#!/usr/bin/env bash
echo "ask result"
result="$(./test-cursor-embed)"
echo "got result=[$result]"
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/318110.html
標籤:
下一篇:如何防止sed插入空白?
