Linux bash: странное поведение после получения позиции курсора терминала - PullRequest
1 голос
/ 27 мая 2020

Я написал сценарий оболочки для сбора и отображения некоторой информации после успешного входа в систему. Однако для сбора некоторой информации требуется некоторое время, поэтому я печатаю на терминал (s sh putty) впереди некоторые заголовки и уже доступную информацию до go назад и печатаю отложенную информацию в нужном месте.

Чтобы выполнить sh, я использовал следующий сценарий, чтобы получить текущую позицию курсора (игнорируя все скучные вещи, которые были раньше. Это набор 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 '\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)\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 .as c

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? Откуда взялось go значение переменной col ?

6) Еще более странно. Я не давал указания печатать второй раз, даже в этом случае, теперь переменная строка имеет кризис идентичности и отображает значение col , и в обоих случаях инструкция col = 56 кажется быть проигнорированным. Почему и как переменная строка получила значение переменной col ? Почему переменная col сместилась с неправильного значения 1 на неправильное значение 0?

7) Показанный сценарий был преобразован для отслеживания ошибки. Он начался с того, что печать не в ожидаемой позиции и ошибки отображения. Также версия printf printf '(r= %d, c= %d)\n' $((${line} - 10)) ${col} отображает одинаково похожую и причудливую ошибку.


ps

После некоторых дополнительных экспериментов только с частью скрипта для получения позиции курсора терминала , кажется также, что это не совсем разумно. Он нормально возвращает позицию, но пытается сделать что-то вроде read r c < <(curspos) (при условии, что curspos - это имя скрипта, который возвращает кортеж lin col), приглашение зависает, пока не будет нажата Ctrl- C и после этого запрос сходит с ума.

Спасибо

1 Ответ

2 голосов
/ 27 мая 2020

Проблема в том, что вы указываете значение в массиве.

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

Это говорит bash игнорировать пробелы и рассматривать его как одно значение. Поэтому, когда вы получите первое значение с ${rowscols[0]} позже, вы фактически получите 16 1 вместо 16, а второго значения нет.

Он также работал с этим printf, потому что вы не указали значения там.

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

Я не знаю, почему он дважды запускал последний printf, но, похоже, это решено с помощью цитирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...