BASH Shell Interactive Session - 如何修复 ASCII 艺术动画输出?
BASH Shell Interactive Session - How to fix ASCII art animation output?
我正在尝试为以下 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
优点:
- 简单approach/solution
- 不需要复杂的变量替换(在 tput cup 屏幕位置)
- 在按下任何键之前效果很好,因此 运行 动画的生命周期不需要硬编码的 COUNTER 变量。
- 动画有点工作(动画正在发生,但输出渲染不完美)。
缺点:
- 动画输出为GARBLED/SHITTY。
如何修复输出?
当您切换到原始模式换行符 (\n
) 时,不再将光标移回第一列。他们只会将它向下移动一条线。您必须打印回车 returns (\r
) 才能重置列。
您可以通过使用 sed 禁用将它们添加到每一行的末尾来做到这一点:
sed 's/$/\r/g' ~/aks1.txt
或者,您可以跳过切换到原始模式的步骤,让终端保持默认状态。要防止 read
命令阻塞,请使用 read -t 0
添加 0 秒超时。如果用户没有按下某个键,它会立即 return 而不是等待他们按下某些东西。
until read -t 0; do
...
done
这个版本在 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
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.
参考post:Animate ASCII art with tput cup until user presses a key
这是 "my theme") 试试这个。
#!/bin/bash
sprites=( "$(cat aks1.txt)" "$(cat aks2.txt)" )
XY () { printf "\e[;H"; }
animation () {
for sprite in "${sprites[@]}"; {
sleep 0.5
XY 1 1 "$sprite"
}
animation
}
animation
我正在尝试为以下 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
优点:
- 简单approach/solution
- 不需要复杂的变量替换(在 tput cup 屏幕位置)
- 在按下任何键之前效果很好,因此 运行 动画的生命周期不需要硬编码的 COUNTER 变量。
- 动画有点工作(动画正在发生,但输出渲染不完美)。
缺点:
- 动画输出为GARBLED/SHITTY。
如何修复输出?
当您切换到原始模式换行符 (\n
) 时,不再将光标移回第一列。他们只会将它向下移动一条线。您必须打印回车 returns (\r
) 才能重置列。
您可以通过使用 sed 禁用将它们添加到每一行的末尾来做到这一点:
sed 's/$/\r/g' ~/aks1.txt
或者,您可以跳过切换到原始模式的步骤,让终端保持默认状态。要防止 read
命令阻塞,请使用 read -t 0
添加 0 秒超时。如果用户没有按下某个键,它会立即 return 而不是等待他们按下某些东西。
until read -t 0; do
...
done
这个版本在 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
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.
参考post:Animate ASCII art with tput cup until user presses a key
这是 "my theme") 试试这个。
#!/bin/bash
sprites=( "$(cat aks1.txt)" "$(cat aks2.txt)" )
XY () { printf "\e[;H"; }
animation () {
for sprite in "${sprites[@]}"; {
sleep 0.5
XY 1 1 "$sprite"
}
animation
}
animation