監視や調査でよく使うワンライナー

アドベンドカレンダー参加してみたかったのでやってみました。すでにいろんな方が書かれてるので用途が被るものはありそうですが、コマンド丸被りという事はないと思うので自分が良く使うやつを。

自分はインフラ周りの業務を担当していて、なんかあったときにec2入ってリソースとかログ確認したりとか、ec2作った時に監視シェルを仕込んだりとかやったりしてるしがないエンジニアです。

##環境
- amazon Linux 2

よくあるコマンドしか使わないのでおおよそのLinuxで使えるだろうとは思います。細かいオプションは変わるかもしれないですが。
行数とか項目の並びとか決め打ちで書いてるとこもあるので、コマンドのversionやら環境に応じて少し調整も必要になるかもしれないです。

##監視や調査でよく使うワンライナー
###ディスク足りなくなって何かファイル消したい時

```
du -l / | sort -n | cut  -f1,2 | awk '{print sprintf ("%5.0dM, %s", $1/1024,$2)}'
```

ディレクトリ容量をMB単位で昇順ソートしつつ表示します。
環境によってはルートディレクトリ指定するとめっちゃ時間かかるので環境に応じて変更してください。
こんな感じででる。

```
...
 2019M, /var/cache/apt/archives
 2108M, /var/cache/apt
 2113M, /var/cache
 2253M, /usr
 2484M, /var
 5155M, /home/username
 5183M, /home
12261M, /
```

###いらなそうなファイルをごっそり退避したい時

```
find ./ -type f ! -atime -180 -exec tar -czf aaa.tgz {} \+ -exec rm -f {} \+
```

特定のディレクトリ配下で180日間アクセスのなかったファイルをaaa.tgzに固めてファイルは消す。
どのファイルを対象にするはfindのオプションで調整します。
コマンド化する場合、aliasではなく下記のようにfunctionとして登録になります。

```
function findshitezip(){
  if [ $# -ne 2 ]; then
    return "usage: findshitezip [atime] [filename]"
  fi
  find ./ -type f ! -atime -$1 -exec tar -czf $2.tgz {} \+ -exec rf -f {} \+
}
```

###特定のプロセス(httpd等)の生死を確認する

```
PID=$(ps axo pid,args | grep httpd | grep -v grep | sed -r 's/^\s//' | cut -d ' ' -f1 | head -n 1)
```

生死というかプロセスがあればプロセスIDを拾います。
監視シェルで使う用で、例のように変数(ex:$PID)に入れておいてその後のif(ex:```if [ -z "$PID" ]; then ... ``` )なんかで用います。
プロセスは一つあれば生きていると判断する場合になりますね。


###CPU使用率チェック

```
CPU_UTIL=$(vmstat 10 2 | awk 'NR==4{use=100-$15;print use}')
```

10秒平均の使用率で0～100の値が$CPU_UTILに入ります。

###デバイス毎にトラフィックチェック

```
sar -n DEV 1 5 | grep 'Average'  | grep 'eth' | awk '{printf("SND=%s;RCV=%s",$6,$5)}'
```

debian系のOSはapt-getでsysstatを入れる必要があります。
１秒当たりの送受信トラフィックを表示。
中身をevalとかに渡してやればシェル内で変数に代入できます。

```
eval $(sar -n DEV 1 5 | grep 'Average'  | grep 'eth' | awk '{printf("SND=%s;RCV=%s",$6,$5)}')
```

###空きメモリチェック（空き使用率）

```
free  | grep 'Mem:' | awk '{printf("%d",$7/$2*100)}'
```

OSのversionによっては/proc/meminfoみないと値が正確じゃなかったりするので注意。
freeコマンドでavailableという項目が表示されるならこれで問題ないはず。

##その他番外編

### ソースを対象にしつつまるっとgrep

```
find ./ -name '*.py' -exec grep -nH '検索する語句' {} \;
```

特定のワードで拡張子がpyのファイルをごっそりgrepし、見つかったファイル名と行数を出力します。ソースだけじゃなく、lotateされてるlogとかをgrepするのにも使えそうです。
こんな感じです。

```
$ find ./ -name '*.py' -exec grep -nH 'sound' {} \;
./app.py:23:drumrole_mp3 = "soundbank://soundlibrary/musical/amzn_sfx_drum_and_cymbal_01"
./app.py:24:question_mp3 = "soundbank://soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_bridge_02"
./app.py:25:correct_mp3 = "soundbank://soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_positive_response_01"
./app.py:26:incorrect_mp3 = "soundbank://soundlibrary/ui/gameshow/amzn_ui_sfx_gameshow_negative_response_01"
./app.py:27:beep_mp3 = "soundbank://soundlibrary/musical/amzn_sfx_electronic_beep_02"
```

### その他、よく使う特殊変数(?)とか

```!$``` = 直前に打ったコマンドの最後の引数をリピート
```!!``` = 直前に打ったコマンドをそのままリピート
```!3``` = historyと対応した行番号を指定し、それを実行

```
$ echo abcdef
abcdef
$ echo !$
abcdef
$ !!
abcdef
$ history | tac | head -n 2
 2032  history | tac | head -n 2
 2031  echo abcdef
$ !2031
abcdef
```
### なんかランダムでファイル作ったりとか処理したりする時にワンライナー

```
for i in `seq 1 10`; do touch $RANDOM.txt; done
```

ただ、10回ループしてランダム名でファイルを作るだけ。なんかテストとかやる時のベース的なやつ。

だいたいこんなところでしょうか。find,grepあたりを一番使ってる気がします。