Определите положение курсора терминала с помощью последовательности ANSI в Python 3Python

Программы на Python
Anonymous
 Определите положение курсора терминала с помощью последовательности ANSI в Python 3

Сообщение Anonymous »

Я хочу написать небольшой скрипт, который печатает изображения на терминал с помощью /usr/lib/w3mimgdisplay(как в mac osx lsi). Поэтому мне нужна фактическая позиция курсора (или позиция курсора) при запуске скрипта. Пока что мне удалось получить позицию курсора в оболочке с помощью последовательности ANSI:

Код: Выделить всё

$ echo -en "\e[6n"
^[[2;1R$ 1R
Вот как выглядит ответ этой ANSI-последовательности (urvxt и bash — не знаю, важно ли это). Итак, эта последовательность выводит результат () немедленно. И вот этого я не понимаю. Как это делается? Если я напишу очень простой сценарий оболочки, только с этой инструкцией и трассировкой сценария, это ничего не прояснит. Что? Затем я пытаюсь выяснить, как это происходит, заглянув в справочную страницу terminfo. Здесь не могу найти (возможно я недостаточно старался). На данный момент я очень запутался в этой концепции. Терминал записывает позицию даже в стандартный вывод?

Терминал

Код: Выделить всё

#!/bin/bash
echo -en "\e[6n"

$ strace sh curpos.sh
[...]
read(255, "#!/bin/bash\necho -en \"\\e[6n\"\n", 29) = 29
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 8), ...}) = 0
write(1, "\33[6n", 4)                   = 4
^[[54;21Rread(255, "", 29)                       = 0
rt_sigprocmask(SIG_BLOCK, [CHLD], [], 8) = 0
rt_sigprocmask(SIG_SETMASK, [], NULL, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++
Python

Сначала я попытался использовать subprocess.check_output, который, конечно, просто возвращает строку, которую я отобразил. Как мне получить ответ на эту последовательность ANSI?

Код: Выделить всё

>>> subprocess.check_output(["echo", "-en", "\x1b[6n"])
b"\x1b[6n"
Я также пробовал много других вещей, например, чтение стандартного ввода и вывода!? С нитями и без них, но все это было скорее догадками и издевательствами, а не знанием, что делать. Я также довольно долго искал в Интернете, надеясь найти пример того, как это сделать, но безуспешно. Я нашел ответ на тот же вопрос: https://stackoverflow.com/a/35526389/2787738, но это не работает. На самом деле я не знаю, работало ли это когда-либо, потому что в этом ответе последовательность ANSI записывается на стандартный вывод до того, как она начинает читать со стандартного ввода? Здесь я снова осознал, что не понимаю концепцию/механизм того, как на самом деле работают эти ANSI-последовательности. Так что на данный момент каждое объяснение, которое проясняет ситуацию, очень ценно. Самый полезный пост, который я нашел, был этот: https://www.linuxquestions.org/question ... -c-947833/. В этой теме кто-то разместил этот bash-скрипт:

Код: Выделить всё

#!/bin/bash
# Restore terminal settings when the script exits.
termios="$(stty -g)"
trap "stty '$termios'" EXIT
# Disable ICANON ECHO. Should probably also disable CREAD.
stty -icanon -echo
# Request cursor coordinates
printf '\033[6n'
# Read response from standard input; note, it ends at R, not at newline
read -d "R" rowscols
# Clean up the rowscols (from \033[rows;cols -- the R at end was eaten)
rowscols="${rowscols//[^0-9;]/}"
rowscols=("${rowscols//;/ }")
printf '(row %d, column %d) ' ${rowscols[0]} ${rowscols[1]}
# Reset original terminal settings.
stty "$termios"
Здесь мы видим, что ответ действительно каким-то волшебным образом появляется на экране :). Вот почему этот скрипт отключает эхо на терминале и после прочтения ответа сбрасывает исходные настройки терминала через stty.

Подробнее здесь: https://stackoverflow.com/questions/466 ... n-python-3

Вернуться в «Python»