【问题标题】:BASH Shell Interactive Session - How to fix ASCII art animation output?BASH Shell 交互会话 - 如何修复 ASCII 艺术动画输出?
【发布时间】:2020-04-15 22:36:13
【问题描述】:

我正在尝试为以下 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 杯屏幕位置)
  3. 在按下任意键之前都可以正常工作,因此运行动画生命周期不需要硬编码的 COUNTER 变量。
  4. 动画有点效果(动画正在发生,但输出渲染不完美)。

缺点:

  1. 动画输出是乱码/垃圾。

如何修复输出?

【问题讨论】:

    标签: linux bash shell animation ascii-art


    【解决方案1】:

    当您切换到原始模式时,换行符 (\n) 不再将光标移回第一列。他们只会把它移到一条线上。您必须打印回车符 (\r) 才能重置该列。

    您可以通过使用 sed 禁用将它们添加到每一行的末尾来做到这一点:

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

    或者,您可以跳过切换到原始模式并让终端保持默认状态。要防止 read 命令阻塞,请使用 read -t 0 添加 0 秒超时。如果用户没有按下某个键,它将立即返回,而不是等待他们按下某个键。

    until read -t 0; do
        ...
    done
    

    【讨论】:

      【解决方案2】:

      这个版本在 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
      

      【讨论】:

        【解决方案3】:

        这是“我的主题”)试试这个。

        #!/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
        

        并查看thisthis 项目以获取有关动画的更多想法)

        【讨论】:

          【解决方案4】:

          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 对任何新的交互式登录shell 都有效。

          参考帖:Animate ASCII art with tput cup until user presses a key

          【讨论】:

          • Arun -1 您自己的答案似乎解决了核心问题,即每行末尾缺少\r,但@JohnKugelman 早些时候已经回答了这个问题。为什么不接受他的回答?对创建别名的其他引用似乎与您的原始问题无关。
          • @rtx13 我原来的帖子使用了别名,所以我也加入了这个。我确实接受了他的回复作为答案并投了赞成票。 until 没用。
          猜你喜欢
          • 1970-01-01
          • 2021-12-04
          • 1970-01-01
          • 1970-01-01
          • 2013-06-27
          • 1970-01-01
          • 1970-01-01
          • 2017-05-24
          • 1970-01-01
          相关资源
          最近更新 更多