shell腳本硬件信息獲取json數(shù)值輸出

簡(jiǎn)介

查看硬件信息,并將信息整合成json數(shù)值,然后傳給前段進(jìn)行分析,最后再進(jìn)行相應(yīng)的處理。在裝系統(tǒng)的時(shí)候,或是進(jìn)行監(jiān)控時(shí),都是一個(gè)標(biāo)準(zhǔn)的自動(dòng)化運(yùn)維流程。使用shell直接生成好json數(shù)據(jù)再進(jìn)行傳輸,會(huì)變得非常方便。所以抽時(shí)間寫了這個(gè)小腳本,供大家參考,里面還有很多不完善的地方,有興趣的朋友可以自行更改

環(huán)境

需要安裝必要的軟件,這里我為了保障腳本合理的進(jìn)行,使用的是真機(jī)環(huán)境,沒(méi)有使用虛擬機(jī)

[root@sys-idc-pxe01 ~]# yum install jq lsscsi MegaCli
Loaded plugins: fastestmirror, security
Loading mirror speeds from cached hostfile
Setting up Install Process
Package jq-1.3-2.el6.x86_64 already installed and latest version
Package lsscsi-0.23-3.el6.x86_64 already installed and latest version
Package MegaCli-8.00.40-1.i386 already installed and latest version
Nothing to do

腳本內(nèi)容

我的shell風(fēng)格比較偏向模塊化,所以使用函數(shù)會(huì)多一些,這樣方便理解,相信大家也能看得懂。
我不太喜歡python風(fēng)格的代碼格式(雖然我python寫的也很不錯(cuò)),看起來(lái)給人的感覺(jué)太緊湊,太亂。據(jù)說(shuō)是前輩們出版書籍的時(shí)候?yàn)榱耸〖?,才出現(xiàn)的那種風(fēng)格,后輩懷著對(duì)前輩的敬仰就延續(xù)了下來(lái),其實(shí)前輩也沒(méi)有那么寫過(guò)那種風(fēng)格的代碼,不知道是不是真的。O(∩_∩)O

[root@sys-idc-pxe01 ~]# cat ./get_server_info.sh 
#!/bin/sh
#description: get server hardware info
#author: liuxin
#date: 20180122
#需要安裝jq工具 yum install jq

#用于存放該服務(wù)器的所有信息,個(gè)人喜歡把全局變量寫到外面
#寫到函數(shù)里面,沒(méi)有加local的變量也是全局變量
INFO="{}"

#定義一個(gè)工具函數(shù),用于生成json數(shù)值,后面將會(huì)頻繁用到
function create_json()
{
  #utility function
  local key=$1
  local value="$2"
  local json=""

  #if value is string
  if [ -z "$(echo "$value" |egrep "\[|\]|\{|\}")" ]
  then
    json=$(jq -n {"$key":"\"$value\""})
  #if value is json, object
  elif [ "$(echo "$value" |jq -r type)" == "object" ]
  then
    json=$(jq -n {"$key":"$value"})
  #if value is array
  elif [ "$(echo "$value" |jq -r type)" == "array" ]
  then
    json=$(jq -n "{$key:$value}")
  else
    echo "value type error..."
    exit 1
    return 0
  fi
  echo $json
  return 0
}

#獲取CPU信息
function get_cpu()
{
  #獲取cpu信息,去掉空格和制表符和空行,以便于for循環(huán)
  local cpu_model_1=$(dmidecode -s processor-version |grep '@' |tr -d " " |tr -s "\n" |tr -d "\t")
  local cpu_info="{}"
  local i=0

  #因?yàn)槿サ袅丝崭窈椭票矸?,以下默認(rèn)使用換行符分隔
  for line in $(echo "$cpu_model_1")
  do
    local cpu_model="$line"
    local cpu1=$(create_json "cpu_model" "$cpu_model")
    #獲取每塊cpu的信息,這里只記錄了型號(hào)
    local cpu=$(create_json "cpu_$i" "$cpu1")
    local cpu_info=$(jq -n "$cpu_info + $cpu")
    i=$[ $i + 1]
  done

  #將cpu的信息整合成一個(gè)json,key是cpu
  local info=$(create_json "cpu" "$cpu_info")
  #將信息加入到全局變量中
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_mem()
{

  #generate json {Locator:{sn:sn,size:size}}
  local mem_info="{}"
  #獲取每個(gè)內(nèi)存的信息,包括Size:|Locator:|Serial Number:
  local mem_info_1=$(dmidecode -t memory |egrep 'Size:|Locator:|Serial Number:' |grep -v 'Bank Locator:' |awk '
  {
    if (NR%3==1 && $NF=="MB")
    {
      size=$2;
      getline (NR+1);
      locator=$2;
      getline (NR+2);
      sn=$NF;
      printf("%s,%s,%s\n",locator,size,sn)
    }
  }')

  #根據(jù)上面的信息,將信息過(guò)濾并整合成json
  local i=0
  for line in $(echo "$mem_info_1")
  do
    local locator=$(echo $line |awk -F , '{print $1}')
    local      sn=$(echo $line |awk  -F , '{print $3}')
    local    size=$(echo $line |awk -F , '{print $2}')

    local mem1=$(create_json "locator" "$locator")
    local mem2=$(create_json "sn" "$sn")
    local mem3=$(create_json "size" "$size")
    local mem4=$(jq -n "$mem1 + $mem2 + $mem3")
    #每條內(nèi)存的信息,key是內(nèi)存從0開(kāi)始的序號(hào)
    local mem=$(create_json "mem_$i" "$mem4")
    #將這些內(nèi)存的信息組合到一個(gè)json中
    mem_info=$(jq -n "$mem_info + $mem")
    i=$[ $i + 1 ]
  done

  #給這些內(nèi)存的信息設(shè)置key,mem
  local info=$(create_json "mem" "$mem_info")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_megacli_disk()
{
  #設(shè)置megacli工具的路徑,此條可以根據(jù)情況更改
  local raid_tool="/opt/MegaRAID/MegaCli/MegaCli64"
  #將硬盤信息獲取,保存下來(lái),省去每次都執(zhí)行的操作
  $raid_tool pdlist aall >/tmp/megacli_pdlist.txt

  local disk_info="{}"
  #獲取硬盤的必要信息
  local disk_info_1=$(cat /tmp/megacli_pdlist.txt |egrep 'Enclosure Device ID:|Slot Number:|PD Type:|Raw Size:|Inquiry Data:|Media Type:'|awk '
{
  if(NR%6==1 && $1$2=="EnclosureDevice")
  {
    E=$NF;
    getline (NR+1);
    S=$NF;
    getline (NR+2);
    pdtype=$NF;
    getline (NR+3);
    size=$3$4;
    getline (NR+4);
    sn=$3$4$5$6;
    getline (NR+5);
    mediatype=$3$4$5$6;
    printf("%s,%s,%s,%s,%s,%s\n",E,S,pdtype,size,sn,mediatype)
  }
}')

  #將獲取到的硬盤信息進(jìn)行整合,生成json
  local i=0
  for line in $(echo $disk_info_1)
  do
    #local       key=$(echo $line |awk -F , '{printf("ES%s_%s\n",$1,$2)}')
    local         E=$(echo $line |awk -F , '{print $1}')
    local         S=$(echo $line |awk -F , '{print $2}')
    local    pdtype=$(echo $line |awk -F , '{print $3}')
    local      size=$(echo $line |awk -F , '{print $4}')
    local        sn=$(echo $line |awk -F , '{print $5}')
    local mediatype=$(echo $line |awk -F , '{print $6}')

    local disk1=$(create_json "pdtype" "$pdtype")
    local disk1_1=$(create_json "enclosure_id" "$E")
    local disk1_2=$(create_json "slot_id" "$S")
    local disk2=$(create_json "size" "$size")
    local disk3=$(create_json "sn" "$sn")
    local disk4=$(create_json "mediatype" "$mediatype")
    local disk5=$(jq -n "$disk1 + $disk1_1 + $disk1_2 + $disk2 + $disk3 + $disk4")
    local disk=$(create_json "disk_$i" "$disk5")
    disk_info=$(jq -n "$disk_info + $disk")
    i=$[ $i + 1 ]
  done
  #echo $disk_info
  local info=$(create_json "disk" "$disk_info")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_hba_disk()
{
  #對(duì)于hba卡的硬盤,使用smartctl獲取硬盤信息
  local disk_tool="smartctl"
  local disk_info="{}"
  #lsscsi 需要使用yum install lsscsi 安裝
  local disk_info_1=$(lsscsi -g |grep -v 'enclosu' |awk '{printf("%s,%s,%s,%s\n",$1,$2,$(NF-1),$NF)}')
  local i=0
  for line in $(echo $disk_info_1)
  do
    local         E=$(echo $line |awk -F , '{print $1}' |awk -F ':' '{print $1}' |tr -d '\[|\]')
    local         S=$(echo $line |awk -F , '{print $NF}' |egrep -o [0-9]*)
    local        sd=$(echo $line |awk -F , '{print $(NF-1)}')
    $disk_tool -i $sd >/tmp/disk_info.txt
    local    pdtype="SATA"
    if [ "$(cat /tmp/disk_info.txt |grep 'Transport protocol:' |awk '{print $NF}')" == "SAS" ]
    then
    local    pdtype="SAS"
    fi
    local      size=$(cat /tmp/disk_info.txt |grep 'User Capacity:' |awk '{printf("%s%s\n",$(NF-1),$NF)}' |tr -d '\[|\]')
    local        sn=$(cat /tmp/disk_info.txt |grep 'Serial Number:' |awk '{print $NF}')
    local mediatype="disk"

    local disk1=$(create_json "pdtype" "$pdtype")
    local disk1_1=$(create_json "enclosure_id" "$E")
    local disk1_2=$(create_json "slot_id" "$S")
    local disk2=$(create_json "size" "$size")
    local disk3=$(create_json "sn" "$sn")
    local disk4=$(create_json "mediatype" "$mediatype")
    local disk5=$(jq -n "$disk1 + $disk1_1 + $disk1_2 + $disk2 + $disk3 + $disk4")
    local disk=$(create_json "disk_$i" "$disk5")
    disk_info=$(jq -n "$disk_info + $disk")
    i=$[ $i + 1 ]
  done
  #echo $disk_info
  local info=$(create_json "disk" "$disk_info")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_disk()
{
  #根據(jù)獲取到的硬盤控制器類型,來(lái)判斷使用什么工具采集硬盤信息
  if [ "$(echo "$INFO" |jq -r .disk_ctrl.disk_ctrl_0.type)" == "raid" ]
  then
    get_megacli_disk
  elif [ "$(echo "$INFO" |jq -r .disk_ctrl.disk_ctrl_0.type)" == "hba" ]
  then
    get_hba_disk
  else
    local info=$(create_json "disk" "error")
    INFO=$(jq -n "$INFO + $info")
  fi
  #hp機(jī)器比較特殊,這里我沒(méi)有做hp機(jī)器硬盤信息采集,有興趣的朋友可以自行添加上
  #if hp machine

  return 0
}

function get_diskController()
{
  local disk_ctrl="{}"
  #if LSI Controller
  local disk_ctrl_1="$(lspci -nn |grep LSI)"
  local i=0
  
  #以換行符分隔
  IFS_OLD=$IFS && IFS=$'\n'
  for line in $(echo "$disk_ctrl_1")
  do
    #echo $line
    local   ctrl_id=$(echo "$line" |awk -F ']:' '{print $1}' |awk '{print $NF}' |tr -d '\[|\]')

    case "$ctrl_id" in
    #根據(jù)控制器的id或進(jìn)行判斷是raid卡還是hba卡,因?yàn)槠放票容^多,后續(xù)可以在此處進(jìn)行擴(kuò)展添加
    0104)
      # 獲取Logic以后的字符串,并進(jìn)行拼接
      local ctrl_name=$(echo "${line##*"Logic"}" |awk '{printf("%s_%s_%s\n",$1,$2,$3)}')
      local     ctrl1=$(create_json "id" "$ctrl_id")
      local     ctrl2=$(create_json "type" "raid")
      local     ctrl3=$(create_json "name" "$ctrl_name")
      ;;
    0100|0107)
      local ctrl_name=$(echo "${line##*"Logic"}" |awk '{printf("%s_%s_%s\n",$1,$3,$4)}')
      local     ctrl1=$(create_json "id" "$ctrl_id")
      local     ctrl2=$(create_json "type" "hba")
      local     ctrl3=$(create_json "name" "$ctrl_name")
      ;;
    *)
      local     ctrl1=$(create_json "id" "----")
      local     ctrl2=$(create_json "type" "----")
      local     ctrl3=$(create_json "name" "----")
      ;;
    esac
    local ctrl_tmp=$(jq -n "$ctrl1 + $ctrl2 + $ctrl3")
    local ctrl=$(create_json "disk_ctrl_$i" "$ctrl_tmp")
    disk_ctrl=$(jq -n "$disk_ctrl + $ctrl")
    i=$[ $i + 1 ]
  done
  IFS=$IFS_OLD
  local info=$(create_json "disk_ctrl" "$disk_ctrl")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_netcard()
{
  local netcard_info="{}"
  local netcard_info_1="$(lspci -nn |grep Ether)"
  local i=0
  #echo "$netcard_info_1"
  IFS_OLD=$IFS && IFS=$'\n'
  for line in $(echo "$netcard_info_1")
  do
    local     net_id=$(echo $line |egrep -o '[0-9a-z]{4}:[0-9a-z]{4}')
    local   net_id_1=$(echo $net_id |awk -F : '{print $1}')

    case "$net_id_1" in
    8086)
      local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')
      local     type=$(echo $line |egrep -o SFP || echo "TP")
      local     net1=$(create_json "id" "$net_id")
      local     net2=$(create_json "name" "$net_name")
      local     net3=$(create_json "type" "$type")
      ;;
    14e4)
      local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')
      local     type=$(echo $line |egrep -o SFP || echo "TP")
      local     net1=$(create_json "id" "$net_id")
      local     net2=$(create_json "name" "$net_name")
      local     net3=$(create_json "type" "$type")
      ;;
    *)
      local net_name=$(echo "${line##*": "}" |awk '{printf("%s_%s_%s_%s\n",$1,$3,$4,$5)}')
      local     type=$(echo $line |egrep -o SFP || echo "TP")
      local     net1=$(create_json "id" "$net_id")
      local     net2=$(create_json "name" "$net_name")
      local     net3=$(create_json "type" "$type")
      ;;
    esac

    local net1=$(jq -n "$net1 + $net2 + $net3")
    #echo $net
    local net2=$(create_json "net_$i" "$net1")
    netcard_info=$(jq -n "$netcard_info + $net2")
    i=$[ $i + 1 ]

  done
  IFS=$IFS_OLD
  local info=$(create_json "net" "$netcard_info")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

function get_server()
{
  local product=$(dmidecode -s system-product-name |grep -v '^#' |tr -d ' ' |head -n1)
  local manufacturer=$(dmidecode -s system-manufacturer |grep -v '^#' |tr -d ' ' |head -n1)
  local server1=$(create_json "manufacturer" "$manufacturer")
  local server2=$(create_json "product" "$product")
  local server3=$(jq -n "$server1 + $server2")
  local info=$(create_json "basic_info" "$server3")
  INFO=$(jq -n "$INFO + $info")

  return 0
}

ALL_INFO=""
function get_all()
{
  #因?yàn)橛脖P信息的獲取依賴硬盤控制器的信息,所以get_diskController要放到get_disk前面
  get_server
  get_cpu
  get_mem
  get_diskController
  get_disk
  get_netcard

  local sn=$(dmidecode -s system-serial-number |grep -v '^#' |tr -d ' ' |head -n1)
  ALL_INFO=$(create_json "$sn" "$INFO")
  return 0
}

function main()
{
  get_all
  echo $ALL_INFO
  return 0
}

#-------------------------------------------------
main
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,326評(píng)論 25 708
  • # Python 資源大全中文版 我想很多程序員應(yīng)該記得 GitHub 上有一個(gè) Awesome - XXX 系列...
    aimaile閱讀 26,845評(píng)論 6 427
  • GitHub 上有一個(gè) Awesome - XXX 系列的資源整理,資源非常豐富,涉及面非常廣。awesome-p...
    若與閱讀 19,360評(píng)論 4 417
  • 不管愿不愿意,這兩天都是漫天的祝福,但我發(fā)現(xiàn)一個(gè)奇怪的現(xiàn)象,留言中與失戀有關(guān)的比例大幅上升。 我以為是錯(cuò)覺(jué),隨手查...
    安慰記心理小店閱讀 447評(píng)論 5 2
  • 原文地址http://www.cnblogs.com/xrq730/p/5260294.html,轉(zhuǎn)載請(qǐng)注明出處,...
    Hong2018閱讀 499評(píng)論 0 1

友情鏈接更多精彩內(nèi)容