長い処理が終わった時にお知らせして欲しい【Ubuntu】

# 1 はじめに

機械学習とか大量のファイルコピーとかをやっていると結構処理に時間がかかったりします．
そういう時は，だいたいその処理を放置して，たまーに処理が終わっているか確認して，終わっていたら次の作業みたいなことをしていると思います．
実際，自分もそういうことをしていると，「終わったらお知らせして欲しい！」とか「処理終わってたけど，一体何時間かかったんだ・・・」って後からなります．
なので，今回は，mplayerを使ったお知らせコマンドと時間計測用のBashについて書いていきます．

# 2 処理が終わった時にお知らせして欲しい

一番簡単な方法は，ビープ音を鳴らす方法です．
以下のコマンドでビープ音を鳴らすことができます．

```bash
echo $'\a'
```
なので，実際に処理が終わった後に上記のコマンドを実行すれば，処理が終わった後にビープ音が鳴ります．
例えは，５秒スリープした後に，ビープ音を鳴らすのであれば，

```bash
sleep 5;echo $'\a'
```
という感じで書けます．

ただし，機種によっては上記のコマンドでビープ音が鳴らない場合があります．
また，ビープ音嫌いだから違う音でお知らせして欲しいとかあると思います．

そこで，mplayerを使用します．
これは，コマンドライン上で音声ファイルを再生するコマンドです（使用するにはインストールが必要です）．
また，音声ファイルを実行する際には，お使いのUbuntuで予めその音声ファイルの拡張子が再生できるか確認してください．

インストールと実行は以下のコマンドです．

```bash
#install
sudo apt-get install mplayer

#play
mplayer [音声ファイル]
```
音声ファイルは，[フリーの音源](http://soundeffect-lab.info/)などを使用するのが楽だと思います．

さて，Sleepコマンド実行後に音声を鳴らすには，コマンド入力時に以下のように入力します．

```bash
sleep 5;mplayer [音声ファイル] >& /dev/null
```
'>& /dev/null'を入力しているのは，コマンドライン上にmplayerを実行した際に表示される実行結果を表示させないためです．

あとは，「終わったよ！お兄ちゃん♪」とか「処理が終わりましてよ，次のお仕事をしてはいかが？」的な音声ファイルを探すだけで，お仕事が捗るはすです．

# 3 処理時間計測と合わせる

時間の計測は，プログラムに組み込んでしまっても良いのですが，
今回は，汎用性をもたせるためにBashで作成しました．
Bash初めて書いたので，もっといい書き方あるとか，設定方法あるよってことがあれば教えてください．（＞＜；

```bash:time_and_alarm.sh
#!/bin/sh

#alarmsフォルダがなければ作成する
mkdir -p ~/alarms/TimeData

#処理時間を計測したい処理コマンドを受け取る
echo -n 'input command >'
read COM

TIME_A=`date +%s`

#処理時間を計測したい処理
${COM}

TIME_B=`date +%s`

#日時と実行時間の記録
DATE=`date '+%y/%m/%d %H:%M:%S'`
PT=`expr ${TIME_B} - ${TIME_A}`
H=`expr ${PT} / 3600`
PT=`expr ${PT} % 3600`
M=`expr ${PT} / 60`
S=`expr ${PT} % 60`
echo "${DATE} > ${H}:${M}:${S} : ${COM}" >> ~/alarms/TimeData/time_log.txt

#最後に音を鳴らす（不要な場合は，コメントアウト）
mplayer ~/alarms/[使用する音声ファイル] >& /dev/null
```

## 3.1 初期設定

最初に，ホームディレクトリに「alarms」というディレクトリを作成し，そこに，処理が終了した際に鳴らすアラーム音のファイルを格納します．
次に，上記のBashの[使用する音声ファイル]を「alarms」に格納した音声ファイル名に変更します．
最後に，使用するディレクトリに，上記のBashファイルをコピーします．

## 3.2 使い方

上記のBashを起動します．

```Bash
bash time_and_alarm.sh
```
起動したら実行するコマンドを入力します．
例として，Sleep 3を実行してみます．

```
input command >sleep 3
```
３秒後にアラーム音が鳴れば正常に動作しています．

出力結果は~/alarms/TimeData/time_log.txtに格納されます．

```text:time_log.txt
17/04/01 16:44:58 > 0:0:3 : sleep 3
```
ファイルフォーマットは，以下のとおりです．

```text
[書き込んだ日時] > [処理時間] : [実行したコマンド]
```
# 4 おわりに

処理時間の計測と終了時にアラームを鳴らしてくれるBashを作成してみました．
初めて，Bash作ってみましたが参考サイトなどを読めばなんとなく作れますね．

あとは，こんなことができればいいな〜と思っています．

- エラーの時に違う音声でお知らせ
- コマンド引数として，テキストログファイル名を渡して，テキストログファイルを違う名前に変更
- Bashファイルをどこでも実行できるようにしたい【追記解決】

#【追記】５　自作shをどこでも使えるようにする

後輩に聴いて解決したので，追記します．

```bash
# time_and_alarm.shを/usr/local/binにコピーする
sudo cp time_and_alarm.sh /usr/local/bin
```
これだけです．あとは，使いたいディレクトリで，

```bash
bash time_and_alarm.sh
```
として呼び出せます．

## 5.1 注意

設定によっては（？），「Syntax error: Bad fd number」というエラーが出て終了する場合があります．
この場合は，下記の行の「&」を消してください[[7]](https://rcmdnk.com/blog/2014/11/03/computer-travisci/)．

```bash
mplayer ~/alarms/[使用する音声ファイル] >& /dev/null
```

# 参考サイト

[1][コマンドの終了時に好きな音を鳴らす方法](http://atmarksharp.v01.jp/posts/long-command-play-sound.html)
[2][シェルプログラムで処理時間計測やタイムスタンプ出力](http://www.tomiryu.com/others/timestam/)
[3][初心者向けシェルスクリプトの基本コマンドの紹介](http://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337)
[4][bashで変数の中のコマンドを実行](http://labs.opentone.co.jp/?p=5651)
[5][Linux : ファイルにテキストを追記で書き込む](http://blog.dacelo.info/linux/entry-979.html)
[6][mkdirでディレクトリが存在しない時だけディレクトリを作成する。](http://blog.katty.in/4967)
[7][プログラムからのシステムコール等でSyntax error: Bad fd numberが出た時の対処](https://rcmdnk.com/blog/2014/11/03/computer-travisci/)