Linux上でシステム情報を拾ってくるシェルスクリプト

# はじめに
初Qiita投稿です。
サーバの情報を調べるためのシェルを作成しました。半分会社の研修です。

コマンドでひとつひとつ拾ってきてもよいのですが、一発でバチッと取ってこれると楽だと思って作りました。
自社サーバやお客さんのサーバの情報をとりあえず知りたい、でも情報が古かったり、ドキュメントがない、という場合に使えるかと思います。

正規表現とawkは便利ですね。

# 機能
以下の情報を取得することができます。

- CPU
- メモリ/スワップ[MB]
- ディストリビューション名
- ネットワーク情報[ホスト名/IPアドレス/サブネットマスク/デフォルトゲートウェイ]
- ディスク容量[GB]


##使い方

基本は```./sysinfo.sh ```+オプション指定```-[acnvmdh]```です。

- ```-a``` : [CPU/メモリ/ディストリビューション/ネットワーク情報/ディスク容量]を表示
- ```-c``` : [CPU]を表示
- ```-m``` : [メモリ]を表示
- ```-v``` : [ディストリビューション]を表示
- ```-n``` : [ネットワーク情報]を表示
- ```-d``` : [ディスク容量]を表示
- ```-h/?``` : [ヘルプ]を表示


**オプションが間違っている、または指定されていない場合、ヘルプメッセージが表示されます。**
```./sysinfo.sh ``` または```./sysinfo.sh -x```など（後述）


###(A) とりあえず全部拾ってくる
```./sysinfo.sh -a```


実行結果(A) 

```
[root@hogehoge ~]# ./sysinfo.sh -a
        CPU info.
          CPU :  Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz
        Memory info.
          Memory Total : 1914.59MB
          SWAP Total : 2031.61MB
        Disk info.
          Disk : 64.4245GB
        Distribution info.
          Version : CentOS release 6.8 (Final)
        Network info.
          Hostname : hogehoge.local
          IPAdress/SubnetMask : 192.168.1.1/255.255.255.0
          DefaultGW : hogehoge.jp
```


###(B) CPUとメモリだけ
```./sysinfo.sh -cm```


実行結果(B) 

```
[root@hogehoge ~]# ./sysinfo.sh -cm
        CPU info.
          CPU :  Intel(R) Core(TM) i5-6400 CPU @ 2.70GHz
        Memory info.
          Memory Total : 1914.59MB
          SWAP Total : 2031.61MB
```



###(C) オプションを間違えた時
```./sysinfo.sh -x```


実行結果(C) 

```
[root@hogehoge ~]# ./sysinfo.sh -x
~/sysinfo.sh: illegal option -- x
        ./sysinfo.sh -[acnvmdh?]
        Usage options:
          -a : All information.
          -c : CPU info.
          -n : Network info.
          -v : Distribution info.
          -m : Memory info.
          -d : Disk info.
          -h/-?/No options or illegal options: Showing help (This page).
```






##シェルスクリプト


### 動作環境
Linux CentOS 6.8(final)で動作確認しました。
CentOS 7ではコマンドや表示が大幅に変わっているため、修正が必要です（特に今後使用されなくなるであろうnetstatとか）。

```sysinfo.sh
#!/bin/bash

#-----------------------------------------------
# ヘルプ情報を表示
# 戻り値：なし
#-----------------------------------------------
_USAGE() {
        cat <<-_EOS_
        ./sysinfo.sh -[acnvmdh?]
        Usage options:
          -a : All information.
          -c : CPU info.
          -n : Network info.
          -v : Distribution info.
          -m : Memory info.
          -d : Disk info.
          -h/-?/No options or illegal options: Showing help (This page).
	_EOS_
        exit 1
}

#-----------------------------------------------
# CPU情報を表示
# 戻り値：なし
#-----------------------------------------------
_CPU_INFO() {
        CPU=`cat /proc/cpuinfo | grep name | cut -d: -f2 | tail -1`
        cat <<-_EOS_
        CPU info.
          CPU : $CPU
	_EOS_
}

#-----------------------------------------------
# ネットワーク情報を表示
# 戻り値：なし
#-----------------------------------------------
_NETWORK_INFO() {
        HOST=`hostname`
        IP=`ifconfig | grep 'inet addr' | grep -v 127.0.0.1 | awk '{print$2;}' | cut -d: -f2`
        SM=`ifconfig | grep 'inet addr' | grep -v 127.0.0.1 | awk '{print$4;}' | cut -d: -f2`
        GW=`netstat -r | grep default | awk '{print$2}'`
        cat <<-_EOS_
        Network info.
          Hostname : $HOST
          IPAdress/SubnetMask : $IP/$SM
          DefaultGW : $GW
	_EOS_
}

#-----------------------------------------------
# ディストリビューションを表示
# 戻り値：なし
#-----------------------------------------------
_VERSION_INFO() {
        TEMP=`ls /etc -F | grep "release$¥|version$"`
        DIST=`cat /etc/$TEMP`
        cat <<-_EOS_
        Distribution info.
          Version : $DIST
	_EOS_
}

#-----------------------------------------------
# メモリを表示[MB]
# 戻り値：なし
#-----------------------------------------------
_MEMORY_INFO() {
        MEM=`cat /proc/meminfo | grep MemTotal | awk '{print$2/1000"MB"}'`
        SWAP=`cat /proc/meminfo | grep SwapTotal | awk '{print$2/1000"MB"}'`
        cat <<-_EOS_
        Memory info.
          Memory Total : $MEM
          SWAP Total : $SWAP
	_EOS_
}

#-----------------------------------------------
# ディスク容量を表示[GB]
# 戻り値：なし
#-----------------------------------------------
_DISK_INFO() {
        LANG=C DISK=`sudo fdisk -l | grep Disk | awk 'NR==1{print$5/1000000000"GB"}'`
        cat <<-_EOS_
        Disk info.
          Disk : $DISK
	_EOS_
}

#-----------------------------------------------
# オプションで指定された情報を表示
# 戻り値：なし
# オプションが[ない/不正]の場合ヘルプ
#-----------------------------------------------
if [ `echo "$1" | grep "^-[a-z]"` ]; then
        while getopts 'acnvmd' OPT; do
                case $OPT in
                  a ) FLA_A="TRUE" ;;
                  c ) FLA_C="TRUE" ;;
                  n ) FLA_N="TRUE" ;;
                  v ) FLA_V="TRUE" ;;
                  m ) FLA_M="TRUE" ;;
                  d ) FLA_D="TRUE" ;;
                  :|h|¥? ) FLA_H="TRUE" ;;
                  * ) FLA_H=TRUE;
                esac
        done
else
        _USAGE
fi

# 全部表示
if [ "$FLA_A" = "TRUE" ]; then
        _CPU_INFO
        _MEMORY_INFO
        _DISK_INFO
        _VERSION_INFO
        _NETWORK_INFO
fi

# CPU用の関数を呼び出し
if [ "$FLA_C" = "TRUE" ]; then
        _CPU_INFO
fi

# ネットワーク情報用の関数を呼び出し
if [ "$FLA_N" = "TRUE" ]; then
        _NETWORK_INFO
fi

# ディストリビューション用の関数を呼び出し
if [ "$FLA_V" = "TRUE" ]; then
        _VERSION_INFO
fi

# メモリ用の関数を呼び出し
if [ "$FLA_M" = "TRUE" ]; then
        _MEMORY_INFO
fi

# ディスク用の関数を呼び出し
if [ "$FLA_D" = "TRUE" ]; then
        _DISK_INFO
fi

# オプション用の関数を呼び出し
if [ "$FLA_H" = "TRUE" ]; then
        _USAGE
fi

exit 0
```






#おわりに
改行コード```^M```と```EOS```前のインデントが曲者で、「予期しない終了～～」のコンパイルエラー原因を特定するまで苦労しました。
前者はテキストエディタで検索・置換できず、viを使って初めて目に見えるとは知りませんでした。後者はヒアドキュメントEOSのインデントに、スペースが使えないことを知らなかったためです。
目に見えるコードにエラーがないのなら、目に見えないところを疑ってみる、という点で勉強になりました。


#参考
[シェルスクリプトを書くときに気をつける9箇条](http://qiita.com/b4b4r07/items/9ea50f9ff94973c99ebe)
[bashのヒアドキュメントを活用する](http://qiita.com/take4s5i/items/e207cee4fb04385a9952)
[Linux/UNIXで文字列から特定部分(右から・左から何個、〇〇~〇〇まで)を抜き出すコマンド - 俺的備忘録 〜なんかいろいろ〜]
(https://orebibou.com/2016/02/linuxunix%E3%81%A7%E6%96%87%E5%AD%97%E5%88%97%E3%81%8B%E3%82%89%E7%89%B9%E5%AE%9A%E9%83%A8%E5%88%86%E5%8F%B3%E3%81%8B%E3%82%89%E3%83%BB%E5%B7%A6%E3%81%8B%E3%82%89%E4%BD%95%E5%80%8B%E3%80%81%E3%80%87/)