bashでyou are idiotを作ってみる
実行イメージ
実行環境
- Ubntu 20.04LTS
- GNU bash, version 5.0.17(1)
使用したもの
tputコマンド
tputコマンドを使うとターミナル標準出力の色を変えたり、カーソルを移動させたりすることができます。
これを使ってyou are idiotの白と黒に画面が点滅する部分を再現するのに使いました。
tput setab 0 #文字の色を黒に
tput setaf 7 #背景色を白に
色番号 | 色 |
0 | 黒 |
1 | 赤 |
2 | 緑 |
3 | 黄色 |
4 | 青 |
5 | マゼンタ |
6 | シアン |
7 | 白 |
trap
スクリプト終了時に関数を実行したり、Ctrl-Cのシグナルをキャプチャして関数を実行したりできます。
本当はターミナルを閉じた時に新しいウィンドウが立ち上がるようにしたかったのですが、それではbashで実装した意味がないような気がしたのでニコチャンマーク(☺)の数が増えるようにしました。
figlet
You are idiot! hahahahahahahahahaha~の音声ファイルを流したかったところはありますが、sayコマンドで機械音声を流してもあんまり雰囲気がでなかったので代わりに大きな文字が表示できるようにしました。
figletはaptで簡単にインストールできます。
sudo apt install figlet
figlet YOU ARE IDIOT
__ _____ _ _ _ ____ _____ ___ ____ ___ ___ _____
\ \ / / _ \| | | | / \ | _ \| ____| |_ _| _ \_ _/ _ \_ _|
\ V / | | | | | | / _ \ | |_) | _| | || | | | | | | || |
| || |_| | |_| | / ___ \| _ <| |___ | || |_| | | |_| || |
|_| \___/ \___/ /_/ \_\_| \_\_____| |___|____/___\___/ |_|
完成形(音無し)
以下のスクリプトをコピペして実行すれば動きます。
Ctrl-Cをするたびに☺が3つずつ増えていきます。
#!/bin/bash
##########################################################################
# Name: uareidiot.bash
#
# You are idiot animation
#
# Usage: ./uareidiot.bash
#
# Author: hahahahaha
# Date: 2021/02/27
##########################################################################
function changecolor()
{
tput setab $1
tput setaf $2
}
function cloneface()
{
for ((n=0; n < $cnt; n++));
do
echo -n " ☺ ☺ ☺ "
done
}
function cntplus()
{
let cnt++
}
declare -i cnt=1
trap cntplus {1,2,3,15}
declare -i i=0 t=7 tmp
while true
do
clear
changecolor $i $t && cloneface #echo "☺ ☺ ☺ "
echo -n -e "\n"
figlet "YOU ARE IDIOT"
sleep 1
tmp=$i
i=$t
t=$tmp
done
止め方
このプログラムは実行するとCtrl-CやCtrl-\などのシグナルをキャプチャして☺が増えるようになっているため、プロセスからキルする必要があります。
今回の設定の場合は単純にkillするだけでなく、-KILLオプションを使わないと止まらないのでご注意を!(ターミナルを消してもバックグラウンドで走っています)。
ps -e | grep uareidiot.bash
kill -KILL <process ID>
追記 音を出したい
やはりあのうざい音がでないと面白くないのではと思い、soxを使って音を出すことにしました。
単純に音を出すスクリプトを挿入すると、音声再生が終わるまで次の処理が行われず、点滅が止まってしまう問題が発生しました。そこで、音を出す部分をバックグラウンド処理にしたところ、音がでなくなってしまいましたがsoxの-qオプションをつけることでバックグラウンド処理でも音が出るようになりました。
また、今回は音が被ってしまうのを避けるためにplayのプロセスが存在する間は音声がならないように設定しました。
音源に関しては、youtubeに転がっているものをダウンロードして、ffmpegでいらない部分をカットして使いました。音源は./music/youareidiot.mp3に保存しています。
soxのインストール
sudo apt install sox
sudo apt install libsox-fmt-mp3 #soxのmp3用のパッケージを追加
play test.mp3
音源が再生されていない時のみ音源を再生する(重ねて再生しない)
if ps -e | grep play > /dev/null 2>&1; then
:
else
play -q ./music/youareidiot.mp3 > /dev/null 2>&1 & #-qオプションでバックグラウンドで実行しても音が出る。
完成形(音あり)
音を出すところ以外に大きな変更点はないですが一応掲載します。
#!/bin/bash
##########################################################################
# Name: uareidiot.bash
#
# You are idiot animation
#
# Usage: ./uareidiot.bash
#
# Author: hahahahaha
# Date: 2021/02/27
##########################################################################
unction changecolor()
{
tput setab $1
tput setaf $2
}
function cloneface()
{
for ((n=0; n < $cnt; n++));
do
echo -n " ☺ ☺ ☺ "
done
}
function cntplus()
{
let cnt++ #number of press Ctrl-C
}
declare -i cnt=1
trap cntplus {1,2,3,15}
declare -i i=0 t=7 tmp
while true
do
clear
figlet "YOU ARE IDIOT"
changecolor $i $t && cloneface
echo -n -e "\n"
if ps -e | grep play > /dev/null 2>&1; then
:
else
play -q ./music/youareidiot.mp3 > /dev/null 2>&1 &
fi
sleep 1
tmp=$i
i=$t
t=$tmp
done
終わりに
ご意見や、改善点などお待ちしております。楽しんでいただければ幸いです。
(自分としては面白いと思って作ったのに反応が薄い気がして悲しいです。ネタが古すぎたのか...)