本家の sl は SIGINT を受け付けないようになっているが、Bash ではできないので、代りに /tmp/tmp.?????? にゴミを残すことにした(ぇ
#!/bin/bash trap "" 1 2 3 set -m tmpdir=`mktemp -d` trap "rm -rf --preserve-root $tmpdir" 0 15 sl_s1=" (@@) ( ) (@) ( ) @@ () @ O @ O @ ( ) (@@@@) ( ) (@@@) " sl_s2=" ( ) (@@) ( ) (@) () @@ O @ O @ O (@@@) ( ) (@@@@) ( ) " sl_b=' ==== ________ ___________ _D _| |_______/ \__I_I_____===__|_________| |(_)--- | H\________/ | | =|___ ___| _________________ / | | H | | | | ||_| |_|| _| \_____A | | | H |__--------------------| [___] | =| | | ________|___H__/__|_____/[][]~\_______| | -| | |/ | |-----------I_____I [][] [] D |=======|____|________________________|' sl_w1=' __/ =| o |=-O=====O=====O=====O \ ____Y___________|__|__________________________|_ |/-=|___|= || || || |_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \__/ \__/ \__/ \__/ \_/ \_/ \_/ \_/ \_/ ' sl_w2=' __/ =| o |=-~~\ /~~\ /~~\ /~~\ ____Y___________|__|__________________________|_ |/-=|___|=O=====O=====O=====O |_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \__/ \__/ \__/ \__/ \_/ \_/ \_/ \_/ \_/ ' sl_w3=' __/ =| o |=-~~\ /~~\ /~~\ /~~\ ____Y___________|__|__________________________|_ |/-=|___|= || || || |_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \O=====O=====O=====O_/ \_/ \_/ \_/ \_/ \_/ ' sl_w4=' __/ =| o |=-~~\ /~~\ /~~\ /~~\ ____Y___________|__|__________________________|_ |/-=|___|= || || || |_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \_O=====O=====O=====O/ \_/ \_/ \_/ \_/ \_/ ' sl_w5=' __/ =| o |=-~~\ /~~\ /~~\ /~~\ ____Y___________|__|__________________________|_ |/-=|___|= O=====O=====O=====O|_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \__/ \__/ \__/ \__/ \_/ \_/ \_/ \_/ \_/ ' sl_w6=' __/ =| o |=-~O=====O=====O=====O\ ____Y___________|__|__________________________|_ |/-=|___|= || || || |_____/~\___/ |_D__D__D_| |_D__D__D_| \_/ \__/ \__/ \__/ \__/ \_/ \_/ \_/ \_/ \_/ ' s=0 w=0 clr="$(tput clear)" cols="$(tput cols || tput co || echo 80)" mkfifo "$tmpdir/pipe" for f in $(seq 1 $((cols+82))); do s=$((s+1)) w=$((w+1)) sf=$((s%2+1)) wf=$((w%6+1)) p=$((cols-f)) p=$(((p<0)?0:p)) hs=$((f-cols)) hs=$(((hs<1)?1:hs)) he=$((hs+cols-p-1)) ( exec 99>"$tmpdir/pipe" echo -n "$clr" >&99 aw=$(eval 'echo "$sl_w'"$wf"'"') as=$(eval 'echo "$sl_s'"$sf"'"') sp=$(printf "%${p}s" "") echo "$as$sl_b$aw" | cut -c $hs-$he 2>/dev/null | sed -e "s:^:$sp:" >&99 2>/dev/null exec 99>&- ) & cat <"$tmpdir/pipe" sleep 0.05 done clear
考え方は sl.js と同じ。端末幅も取得できない(?) ので 80 固定で列車長がたまたま 81 だったので、実はメインのループ内の条件分岐の条件が1つ少ない。
bash さんが遅いので (このプログラムの仕方もどうかと思うが)、clear とそのあとの動作が行われる時間に差が出来て見にくくなるので、こうするしかなかったんだ。だからもしかしたら端末によっては動かないかも。
高速化されました(誰得)。