Подтвердить что ты не робот

Как получить позицию курсора в bash?

В bash script я хочу получить столбец курсора в переменной. Похоже, что использование escape-кода ANSI {ESC}[6n - единственный способ получить его, например, следующим образом:

# Query the cursor position
echo -en '\033[6n'

# Read it to a variable
read -d R CURCOL

# Extract the column from the variable
CURCOL="${CURCOL##*;}"

# We have the column in the variable
echo $CURCOL

К сожалению, это выводит символы на стандартный вывод, и я хочу сделать это тихо. Кроме того, это не очень портативно...

Есть ли способ для чистых bash для достижения этого?

4b9b3361

Ответ 1

Вы должны прибегать к грязным трюкам:

#!/bin/bash
# based on a script from http://invisible-island.net/xterm/xterm.faq.html
exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
# on my system, the following line can be replaced by the line below it
echo -en "\033[6n" > /dev/tty
# tput u7 > /dev/tty    # when TERM=xterm (and relatives)
IFS=';' read -r -d R -a pos
stty $oldstty
# change from one-based to zero based so they work with: tput cup $row $col
row=$((${pos[0]:2} - 1))    # strip off the esc-[
col=$((${pos[1]} - 1))

Ответ 2

Я знаю, что это может быть разрешено знанием, но вы можете просто сказать, что читать тихо работать с "-s":

echo -en "\E[6n"
read -sdR CURPOS
CURPOS=${CURPOS#*[}

И затем CURPOS будет равно чем-то вроде "21; 3".

Ответ 3

В интересах переносимости я пошел на создание совместимой с POSIX версии, которая будет работать в оболочках вроде тире:

#!/bin/sh

exec < /dev/tty
oldstty=$(stty -g)
stty raw -echo min 0
tput u7 > /dev/tty
sleep 1
IFS=';' read -r row col
stty $oldstty

row=$(expr $(expr substr $row 3 99) - 1)        # Strip leading escape off
col=$(expr ${col%R} - 1)                        # Strip trailing 'R' off

echo $col,$row

... но я не могу найти жизнеспособную альтернативу для bash ' read -d. Без сна script полностью пропускает возвращаемый вывод...

Ответ 4

Команды tput - это то, что вам нужно использовать. простой, быстрый, без вывода на экран.

#!/bin/bash
col=`tput col`;
line=`tput line`;