Интерактивный сеанс BASH Shell — как исправить вывод анимации в формате ASCII?

Я пытаюсь оживить следующее искусство ASCII. (Сейчас у меня есть два файла, и я могу добавить больше позже для более точной анимации.)

$ cat ~/aks1.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ]  HHUHH. [  [  [
           ]  ] /   `HN("N  \ [  [
           ]__]/     HNH  "  \[__[
           ]         NNN         [
           ]       / N/" \       [
           ]      /  N H  \      [
          /          N            \
         /           q,            \
        /                           \
$ cat ~/aks2.txt
        \            RTX            /
         \                         /
          \       WAZUH LAB       /
           ]                     [    ,'|
           ]                     [   /  |
           ]___               ___[ ,'   |
           ]  ]\             /[  [ |:   |
           ]  ] \           / [  [ |:   |
           ]  ]  ]         [  [  [ |:   |
           ]  ]  ]__     __[  [  [ |:   |
           ]  ]  ] ]\ _ /[ [  [  [ |:   |
           ]  ]  ] ] (A) [ [  [  [ :===='
           ]  ]  ]_].nRn.[_[  [  [
           ]  ]  ] .HHUHH  [  [  [
           ]  ] /  #")NH`   \ [  [
           ]__]/   " HNH     \[__[
           ]         NNN         [
           ]       / "\N         [
           ]         H N  \      [
          /      /     N   \      \
         /      /     ,p    \      \
        /                           \

Вот мой код:

if [[ -t 0 ]]; then
    old_tty=$(stty --save)
    stty raw -echo min 0
fi
while IFS= read -r REPLY; [[ -z "$REPLY" ]]; do
    clear
    cat ~/aks1.txt
    usleep 500000
    clear
    cat ~/aks2.txt
    ((c++)) && usleep 500000
done
if [[ -t 0 ]]; then
    stty "$old_tty"
fi
echo

Плюсы:

  1. Простой подход/решение
  2. Не требуется подстановка сложных переменных (в местах расположения экранов tput cup)
  3. Работает хорошо до тех пор, пока не будет нажата ЛЮБАЯ клавиша, поэтому для запуска анимации не требуется жестко закодированная переменная COUNTER.
  4. Анимация вроде работает (анимация идет, но вывод не идеально рендерится).

Минусы:

  1. Вывод анимации ИСКАЖЕН/ДЕРЬМОВ.

Как я могу исправить вывод?


person AKS    schedule 15.04.2020    source источник


Ответы (4)


При переключении в необработанный режим новые строки (\n) больше не перемещают курсор обратно в первый столбец. Они только перемещают его вниз по строке. Вы должны напечатать возврат каретки (\r), чтобы сбросить столбец.

Вы можете сделать это, отключив добавление их в конец каждой строки с помощью sed:

sed 's/$/\r/g' ~/aks1.txt

В качестве альтернативы вы можете пропустить переход в необработанный режим и оставить терминал в состоянии по умолчанию. Чтобы команда read не блокировалась, используйте read -t 0, чтобы добавить 0-секундный тайм-аут. Если пользователь не нажал клавишу, он вернется немедленно, а не ждет, пока он что-то нажмет.

until read -t 0; do
    ...
done
person John Kugelman    schedule 15.04.2020

Эта версия отлично работает для меня на debian/xterm:

function animate {
    local aks1="$(cat ~/aks1.txt)"
    local aks2="$(cat ~/aks2.txt)"
    local c
    for (( c=0; c < 5; c++ )); do
        read -rsn1 -t .001 && return
        clear; printf "%s\n" "$aks1"; sleep .5
        clear; printf "%s\n" "$aks2"; sleep .5
    done
    echo
}
setterm -cursor off
animate
setterm -cursor on
person Philippe    schedule 15.04.2020

Это "моя тема") попробуй.

#!/bin/bash

sprites=( "$(cat aks1.txt)" "$(cat aks2.txt)" )

XY () { printf "\e[$2;${1}H$3"; }
animation () {
    for sprite in "${sprites[@]}"; {
        sleep 0.5
        XY 1 1 "$sprite"
    }    
    animation
}

animation

И проверьте это и этот проект, чтобы получить больше идей об анимации)

person Ivan    schedule 16.04.2020

Решение для Animate ASCII ART прерывается при нажатии любой клавиши (используя способ alias):

alias animate_arun='until read -t 0; do clear && cat ~/aks1.txt && sleep .5 && clear && cat ~/aks2.txt && sleep .5; done; echo;'

Помещение вышеуказанного псевдонима в ~/.bash_profile и вызов псевдонима animate_arun сделали свое дело для любой новой интерактивной оболочки входа в систему.

Справочное сообщение: Анимируйте искусство ASCII с помощью чашки tput до пользователь нажимает клавишу

person AKS    schedule 16.04.2020
comment
Арун -1, кажется, ваш собственный ответ касается основной проблемы, заключающейся в отсутствии \r в конце каждой строки, но на это уже ответил ранее @JohnKugelman. Почему бы не принять его ответ? Дополнительные ссылки на создание псевдонима не связаны с вашим исходным вопросом. - person rtx13; 16.04.2020
comment
@ rtx13 В моем исходном сообщении использовался псевдоним, поэтому я включил и его. Я принял его ответ как ответ и проголосовал за него. until не работает. - person AKS; 16.04.2020