ルギア君の戯言

雑多な記事。

SL コマンド

Bash スクリプトで作ってみた。

本家の 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 とそのあとの動作が行われる時間に差が出来て見にくくなるので、こうするしかなかったんだ。だからもしかしたら端末によっては動かないかも。

高速化されました(誰得)。