【shell--批量遠程MySQL,執行命令】-【工作總結】



昨天下班前,老板給了一批LOG數據庫IP地址,需要統計LOG表里Message字段top 10的結果,並輸出到一個excel文件里。
抽查看了下,有兩種格式的以當天日期結尾的表名。由於數量太多,時間緊迫,只好寫批量腳本解決問題。
並以此擴展,解析其中的幾個常用shell程序,主體腳本寫在文章后半部分。
學習shell重在靈活運用命令,形成自己的思維方式,和書寫習慣,腳本參考即可。

解題過程步驟:
1.梳理IP地址及對應表名
2.確定查詢SQL
3.批量查詢數據

完整腳本附在文章最后

解析下常用到的知識點:

1.日期:關於日期結尾的表,表中涉及日期時間的表字段
  注意:shell中養成給日期定義變量的習慣。
  <1>.當前日期時間及格式
    DATE_MARK=`date +'%Y%m%d'`  結果:20161214
    DATE_MARK=`date + '%Y-%m-%d %H:%M:%S'` 結果:2016-12-14 18:20:11
    
    過去日期時間及格式
    DATE_MARK=`date -d'1 day ago' +'%Y%m%d'`  結果:一天之前:20161213
     DATE_MARK=`date -d'1 hour ago' +'%Y-%m-%d %H:%M:%S'` 結果:2016-12-14 17:20:11
    
     修改-d' ' :7天之前:7 days ago 7小時之前:7 hours ago
    
     表名:TB_NAME="LOG_${DATE_MARK}"


2.遍歷思想和循環及行的處理
  <1>.批量遠程執行命令,批量Telnet端口,批量ping主機
  <2>.遍歷文件中每一行,進行添加,截取,輸出操作。
    主體思想:先讀取ip或行,再處理ip或行,再利用ip或行
    實例:
    1.依次輸出文件中的每一行
      命令行while循環遍歷: cat ip.txt | while read line; do echo $line;done
      命令行for 循環遍歷:for line in `cat ip.txt`;do echo $line;done
      腳本中調用:ip.txt,然后循環遍歷. ip文件作為腳本的執行參數
      #!/bin/sh
      ipfile=$1
      cat ${ipfile}|while read line
      do
        echo ${line}
      done  
      腳本執行:./xx.sh ip.txt   
    2.對行的處理,一行有多個分割字段時需要處理
      格式:172.21.1.1,3306 
      截取一行的第一列IP: 
      IP=`echo ${line}|awk -F',' '{print $1}'`
      PORT=`echo ${line}|awk -F',' '{print $2}'`
      awk -F',' '{print $1}' 等同於 cut -f1 -d','
      添加內容:
      echo "${IP}_${PORT}:OK" 結果:172.21.1.1_3306:OK

3.關於自定義函數
  <1>.不傳參函數:
    fun_name()
    {
       name='Kata'   
      echo "My name is ${name}."
    }
    fun_name #調用方式,直接將:My name is Kata.輸出到屏幕   
  <2>.傳參函數
    fun_name()
    {
      name=$1
      echo "My name is ${name}."
    }
  
    fun_name "Alias" #調用方式,直接將:My name is Alias.輸出到屏幕
  <3>.多參函數

    fun_name()
    {
      name=$1
      age=$2
      echo "My name is ${name} and My age is ${age}."
    }
  
    fun_name "Sunny" "18" #調用方式,直接將:My name is Sunny and My age is 18.輸出到屏幕

  <4>.將函數結果賦值給變量
    status=`fun_name "Alias"` #變量status的內容就是:My name is Alias. 此時再將status變量應用到其它程序調用
  <5>.自定義函數事例:統計IP數據庫里對應的表格式是哪種?
    思路:選一種格式表作為判斷,存在做標記,不存在就是另一種。前提條件:每個ip上只存在一種表,避免意外兩種表都試試

    FUN_CHECK()
    {
      ip=$1  #自定義函數傳參
      tb_like=$2
      MYSQL_CMD="/usr/local/mysql/bin/mysql -uadmin -padmin -h${ip} -P3306" #變量只有IP,端口也可定義變量
      SQL="SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='LogDB' AND TABLE_NAME
      = '${tb_like}_${DATE_MARK}';"
      STATUS=`${MYSQL_CMD} -NBe"${SQL}"`  #查詢數據庫表結果賦值給變量
      if [ ${STATUS} == '1' ];then
        echo ${ip}
      else
        echo  #此處輸出空行或者去掉else,可方便將屏幕ip列表復制。甚至不要if判斷,直接:echo "${ip}:${STATUS}" 再篩選。
      fi
    }
    在while循環中調用函數:
    #!/bin/sh
      .
      .
      .
    cat $IP_FILE1|while read line
    do
      IP=`echo $line|cur -f1 -d' '`
      FUN_CHECK "${IP}" "HA_Logging" #手動修改下第二個參數,另一個表也測試下,別遺漏ip。
    done
4.關於輸出文件
  將n個ip上表的查詢數據追加到一個excel里。SQL的查詢結果不要帶表頭。否則文件里會出現多個表頭行。
  通過mysql命令指定NBe參數,只輸出數據結果,不顯示字段名。
  mysql -u -p -h -P -NBe"${sql}"

5.腳本傳參和函數傳參
  腳本的開頭定義:xxx=$1 xxx=$2
  函數的開頭定義:xxx=$1 xxx=$2
  腳本執行:./x.sh 參數1 參數2
  函數調用:fun_name "參數1" "參數2"

附件見下面:

附件腳本1:梳理ip列表,及對應哪種表格式
說明:
腳本執行:執行兩次
./check_ip.sh ip.txt 'HA_Logging'
./check_ip.sh ip.txt 'LOG'
腳本第二個參數:作為表格式模糊查詢的變量傳參

cat check_ip.sh
#!/bin/sh
IPFILE=$1
TB_LIKE=$2
DATE_MARK=`date -d'1 day ago' +'%Y%m%d'`
FUN_CHECK()
    {
      ip=$1  #自定義函數傳參:ip
      tb_like=$2 #自定義函數傳參:HA_Logging或者LOG
      MYSQL_CMD="/usr/local/mysql/bin/mysql -uadmin -padmin -h${ip} -P3306" #變量只有IP,端口也可定義變量
      SQL="SELECT COUNT(*) FROM information_schema.TABLES WHERE TABLE_SCHEMA='LogDB' AND TABLE_NAME
      = '${tb_like}_${DATE_MARK}';"
      STATUS=`${MYSQL_CMD} -NBe"${SQL}"`  #查詢數據庫表結果賦值給變量
      if [ ${STATUS} == '1' ];then
        echo ${ip}
      fi #此處定義 如果存在直接輸出ip,不存在,就不管。
    }
cat ${IPFILE}|while read line
do
  IP=`echo ${line}|cut -f1 -d' '`
  FUN_CHECK "${IP}" "${TB_LIKE}"  
done

附件腳本3:查詢表數據導入Excel
說明:為了一次性執行,將兩個ip列表文件作為腳本參數
腳本執行:./check_loginfo.sh ha_ip.txt log_ip.txt
cat check_loginfo.sh
#!/bin/sh
IP_FILE1=$1
IP_fILE2=$2

# 定義日期標志 : 20161214 (此處是昨天日期)
TIME_MARK=`date -d'1 day ago' +'%Y%m%d'`

# 定義表的名字:以日期結尾的表名 <DB_NAME.TB_NAME_20161214>
HA_TB="LogDB.HA_Logging_${TIME_MARK}"
LO_TB="LogDB.LOG_${TIME_MARK}"

# 對表查詢結果輸出到Excel文件:OUT FILE
OUT_FILE="/data/${TIME_MARK}_log.xls"

# 定義通用函數,從表里查詢數據結果
GET_INFO()
{
ipfile=$1
tbname=$2

cat $ipfile|while read line
do
IP=`echo $line|awk -F' ' '{print $1}'`
MYSQL_CMD="/usr/local/mysql/bin/mysql -uadmin -padmin -h${IP} -P9306"
SQL="SELECT ServiceName,LoggerName,COUNT(LoggerName) AS count_num FROM ${tbname} GROUP BY LoggerName ORDER BY count_num DESC LIMIT 10;"
$MYSQL_CMD -NBe"${SQL}" >>${OUT_FILE}
echo "$IP:ok"
done
}

# 執行調用
#
GET_INFO "${IP_FILE1}" "${HA_TB}"
GET_INFO "${IP_fILE2}" "${LO_TB}"

完結!
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM