11.統(tǒng)計 /proc 目類下 Linux 進程相關(guān)數(shù)量信息,輸出總進程數(shù),running 進程數(shù)贿衍,stoped 進程數(shù),sleeing 進程數(shù)在扰,zombie 進程數(shù)胚股。
【輸出所有 zombie 的進程到 zombie.txt 殺死所有 zombie 進程】
#!/bin/bash
ALL_PROCESS=$(ls /proc/ | egrep '[0-9]+')
running_count=0
stoped_count=0
sleeping_count=0
zombie_count=0
for pid in ${ALL_PROCESS[*]}
do
test -f /proc/$pid/status && state=$(egrep "State" /proc/$pid/status | awk '{print $2}')
case "$state" in
R)
running_count=$((running_count+1))
;;
T)
stoped_count=$((stoped_count+1))
;;
S)
sleeping_count=$((sleeping_count+1))
;;
Z)
zombie_count=$((zombie_count+1))
echo "$pid" >>zombie.txt
kill -9 "$pid"
;;
esac
done
echo -e "total:
$((running_count+stoped_count+sleeping_count+zombie_count))\nrunning:
$running_count\nstoped: $stoped_count\nsleeping: $sleeping_count\nzombie:
$zombie_count"
12.12.把當前目錄(包含子目錄)下所有后綴為 ".sh" 的文件后綴變更為 ".shell",之后刪除每個文件的第二行士八。
#!/bin/bash
ALL_SH_FILE=$(find .-type f -name "*.sh")
for file in ${ALL_SH_FILE[*]}
do
filename=$(echo $file | awk -F'.sh' '{print $1}')
new_filename="${filename}.shell"
mv "$file" "$new_filename"
sed -i '2d' "$new_filename"
done
13.判斷目錄 /tmp/jstack 是否存在容燕,不存在則新建一個目
錄,若存在則刪除目錄下所有內(nèi)容婚度。
【每隔 1 小時打印 inceptor server 的 jstack 信息蘸秘,并以 jstack_${當前時間} 命名文件,每當目錄下超過10 個文件后陕见,刪除最舊的文件】
#!/bin/bash
DIRPATH='/tmp/jstack'
CURRENT_TIME=$(date +'%F'-'%H:%M:%S')
if [ ! -d "$DIRPATH" ];then
mkdir "$DIRPATH"
else
rm -rf "$DIRPATH"/*
fi
cd "$DIRPATH"
while true
do
sleep 3600
# 這里需要將inceptor改后自己的java進程名稱
pid=$(ps -ef | grep 'inceptor' | grep -v grep | awk '{print $2}')
jstack $pid >> "jstack_${CURRENT_TIME}"
dir_count=$(ls | wc -l)
if [ "$dir_count"-gt 10 ];then
rm -f $(ls -tr | head -1)
fi
done
14.從 test.log 中截取當天的所有 gc 信息日志秘血,并統(tǒng)計 gc
時間的平均值和時長最長的時間。
#!/bin/bash
awk '{print $2}' hive-server2.log | tr -d ':' | awk '{sum+=$1} END {print "avg:
", sum/NR}' >>capture_hive_log.log
awk '{print $2}' hive-server2.log | tr -d ':' | awk '{max = 0} {if ($1+0 > max+0)
max=$1} END {print "Max: ", max}'>>capture_hive_log.log
15.查找 80 端口請求數(shù)最高的前 20 個 IP 地址评甜,判斷中間最小的請求數(shù)是否大于 500灰粮,如大于 500,則輸出系統(tǒng)活動情況報告到 alert.txt忍坷,如果沒有粘舟,則在 600s 后重試熔脂,直到有輸出為止。
#!/bin/bash
state="true"
while $state
do
SMALL_REQUESTS=$(netstat -ant | awk -F'[ :]+' '/:22/{count[$4]++} END {for(ip in count) print count[ip]}' | sort -n | head -20 | head -1)
if [ "$SMALL_REQUESTS" -gt 500 ];then
sar -A > alert.txt
state="false"
else
sleep 6
continue
fi
16.將當前目錄下大于 10K 的文件轉(zhuǎn)移到 /tmp 目錄柑肴,再按
照文件大小順序霞揉,從大到小輸出文件名
#!/bin/bash
# 目標目錄
DIRPATH='/tmp'
# 查看目錄
FILEPATH='.'
find "$FILEPATH" -size +10k -type f | xargs -i mv {} "$DIRPATH"
ls -lS "$DIRPATH" | awk '{if(NR>1) print $NF}'
17.企業(yè)微信告警
【此腳本通過企業(yè)微信應用,進行微信告警晰骑,可用于 Zabbix 監(jiān)控适秩。
】
# -*- coding: utf-8 -*-
import requests
import json
class DLF:
def__init__(self, corpid, corpsecret):
self.url ="https://qyapi.weixin.qq.com/cgi-bin"
self.corpid = corpid
self.corpsecret = corpsecret
self._token = self._get_token()
def_get_token(self):
'''
獲取企業(yè)微信API接口的access_token
:return:
'''
token_url = self.url + "/gettoken?corpid=%s&corpsecret=%s" %(self.corpid,
self.corpsecret)
try:
res = requests.get(token_url).json()
token = res['access_token']
return token
except Exception as e:
return str(e)
def_get_media_id(self, file_obj):
get_media_url = self.url + "/media/upload?access_token={}&type=file"
.format(self._token)
data = {"media": file_obj}
try:
res = requests.post(url=get_media_url, files=data)
media_id = res.json()['media_id']
return media_id
except Exception as e:
return str(e)
def send_text(self, agentid, content, touser=None, toparty=None):
send_msg_url = self.url + "/message/send?access_token=%s" %
(self._token)
send_data = {
"touser": touser,
"toparty": toparty,
"msgtype": "text",
"agentid": agentid,
"text": {
"content": content
}
}
try:
res = requests.post(send_msg_url, data=json.dumps(send_data))
except Exception as e:
return str(e)
def send_image(self, agentid, file_obj, touser=None, toparty=None):
media_id = self._get_media_id(file_obj)
send_msg_url = self.url + "/message/send?access_token=%s" %
(self._token)
send_data = {
"touser": touser,
"toparty": toparty,
"msgtype": "image",
"agentid": agentid,
"image": {
"media_id": media_id
}
}
try:
res = requests.post(send_msg_url, data=json.dumps(send_data))
except Exception as e:
return str(e)
18.FTP 客戶端
通過 ftplib 模塊操作 ftp 服務器,進行上傳下載等操作硕舆。
# -*- coding: utf-8 -*-
from ftplib import FTP
from os import path
import copy
class FTPClient:
def__init__(self, host, user, passwd, port=21):
self.host = host
self.user = user
self.passwd = passwd
self.port = port
self.res = {'status': True, 'msg': None}
self._ftp = None
self._login()
def_login(self):
'''
登錄FTP服務器
:return: 連接或登錄出現(xiàn)異常時返回錯誤信息
'''
try:
self._ftp = FTP()
self._ftp.connect(self.host, self.port, timeout=30)
self._ftp.login(self.user, self.passwd)
except Exception as e:
return e
def upload(self, localpath, remotepath=None):
'''
上傳ftp文件
:param localpath: local file path
:param remotepath: remote file path
:return:
'''
if not localpath: return 'Please select a local file. '
# 讀取本地文件
# fp = open(localpath, 'rb')
# 如果未傳遞遠程文件路徑秽荞,則上傳到當前目錄,文件名稱同本地文件
if not remotepath:
remotepath = path.basename(localpath)
# 上傳文件
self._ftp.storbinary('STOR ' + remotepath, localpath)
# fp.close()
def download(self, remotepath, localpath=None):
'''
localpath
:param localpath: local file path
:param remotepath: remote file path
:return:
'''
if not remotepath: return 'Please select a remote file. '
# 如果未傳遞本地文件路徑抚官,則下載到當前目錄扬跋,文件名稱同遠程文件
if not localpath:
localpath = path.basename(remotepath)
# 如果localpath是目錄的話就和remotepath的basename拼接
if path.isdir(localpath):
localpath = path.join(localpath, path.basename(remotepath))
# 寫入本地文件
fp = open(localpath, 'wb')
# 下載文件
self._ftp.retrbinary('RETR ' + remotepath, fp.write)
fp.close()
def nlst(self, dir='/'):
'''
查看目錄下的內(nèi)容
:return: 以列表形式返回目錄下的所有內(nèi)容
'''
files_list = self._ftp.nlst(dir)
return files_list
def rmd(self, dir=None):
'''
刪除目錄
:param dir: 目錄名稱
:return: 執(zhí)行結(jié)果
'''
if not dir: return 'Please input dirname'
res = copy.deepcopy(self.res)
try:
del_d = self._ftp.rmd(dir)
res['msg'] = del_d
except Exception as e:
res['status'] = False
res['msg'] = str(e)
return res
def mkd(self, dir=None):
'''
創(chuàng)建目錄
:param dir: 目錄名稱
:return: 執(zhí)行結(jié)果
'''
if not dir: return 'Please input dirname'
res = copy.deepcopy(self.res)
try:
mkd_d = self._ftp.mkd(dir)
res['msg'] = mkd_d
except Exception as e:
res['status'] = False
res['msg'] = str(e)
return res
def del_file(self, filename=None):
'''
刪除文件
:param filename: 文件名稱
:return: 執(zhí)行結(jié)果
'''
if not filename: return 'Please input filename'
res = copy.deepcopy(self.res)
try:
del_f = self._ftp.delete(filename)
res['msg'] = del_f
except Exception as e:
res['status'] = False
res['msg'] = str(e)
return res
def get_
file_size(self, filenames=[]):
'''
獲取文件大小,單位是字節(jié)
判斷文件類型
:param filename: 文件名稱
:return: 執(zhí)行結(jié)果
'''
if not filenames: return {'msg': 'This is an empty directory'}
res_l = []
for file in filenames:
res_d = {}
# 如果是目錄或者文件不存在就會報錯
try:
size = self._ftp.size(file)
type ='f'
except:
# 如果是路徑的話size顯示 -, file末尾加/ (/dir/)
size ='-'
type ='d'
file = file + '/'
res_d['filename'] = file
res_d['size'] = size
res_d['type'] = type
res_l.append(res_d)
return res_l
def rename(self, old_name=None, new_name=None):
:param new
_
name: 新的文件或者目錄名稱
:return: 執(zhí)行結(jié)果
'''
if not old_name or not new_name: return 'Please input old_name and new_name'
res = copy.deepcopy(self.res)
try:
rename_f = self._ftp.rename(old_name, new_name)
res['msg'] = rename_f
except Exception as e:
res['status'] = False
res['msg'] = str(e)
return res
def close(self):
'''
退出ftp連接
:return:
'''
try:
# 向服務器發(fā)送quit命令
self.
_
ftp.quit()
except Exception:
return 'No response from server'
finally:
# 客戶端單方面關(guān)閉連接
self._ftp.close()
'''
19.SSH 客戶端
此腳本僅用于通過 key 連接,如需要密碼連接凌节,簡單修改下即可钦听。
-- coding: utf-8 --
import paramiko
class SSHClient:
def__init__(self, host, port, user, pkey):
self.ssh_host = host
self.ssh_port = port
self.ssh_user = user
self.private_key = paramiko.RSAKey.from_private_key_file(pkey)
self.ssh = None
self._connect()
def_connect(self):
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
self.ssh.connect(hostname=self.ssh_host, port=self.ssh_port,
username=self.ssh_user, pkey=self.private_key, timeout=10)
except:
return 'ssh connect fail'
def execute_command(self, command):
stdin, stdout, stderr = self.ssh.exec_command(command)
out = stdout.read()
err = stderr.read()
return out, err
def close(self):
self.ssh.close()
20.Saltstack 客戶端
通過 api 對 Saltstack 服務端進行操作,執(zhí)行命令倍奢。
!/usr/bin/env python
-- coding:utf-8 --
import requests
import json
import copy
class SaltApi:
"""
定義salt api接口的類
初始化獲得token
"""
def__init__(self):
self.url ="http://172.85.10.21:8000/"
self.username = "saltapi"
self.password = "saltapi"
self.headers = {"Content-type": "application/json"}
self.params = {'client': 'local', 'fun': None, 'tgt': None, 'arg': None}
self.login_url = self.url + "login"
self.login_params = {'username': self.username, 'password': self.password,
'eauth': 'pam'}
self.token = self.get_data(self.login_url, self.login_params)['token']
self.headers['X-Auth-Token'] = self.token
def get_data(self, url, params):
'''
請求url獲取數(shù)據(jù)
:param url: 請求的url地址
:param params: 傳遞給url的參數(shù)
:return: 請求的結(jié)果
'''
send_data = json.dumps(params)
request = requests.post(url, data=send_data, headers=self.headers)
response = request.json()
result = dict(response)
return result['return'][0]
def get_auth_keys(self):
'''
獲取所有已經(jīng)認證的key
:return:
'''
data = copy.deepcopy(self.params)
data['client'] = 'wheel'
data['fun'] ='key.list_all'
result = self.get_data(self.url, data)
try:
return result['data']['return']['minions']
except Exception as e:
return str(e)
def get_grains(self, tgt, arg='id'):
"""
獲取系統(tǒng)基礎信息
:tgt: 目標主機
:return:
"""
data = copy.deepcopy(self.params)
if tgt:
data['tgt'] = tgt
else:
data['tgt'] = '*'
data['fun'] ='grains.item'
data['arg'] = arg
result = self.get_data(self.url, data)
return result
def execute_command(self, tgt, fun='cmd.run', arg=None, tgt_type='list',salt_async=False):
"""
執(zhí)行saltstack 模塊命令朴上,類似于salt '' cmd.run 'command'
:param tgt: 目標主機
:param fun: 模塊方法 可為空
:param arg: 傳遞參數(shù) 可為空
:return: 執(zhí)行結(jié)果
"""
data = copy.deepcopy(self.params)
if not tgt: return {'status': False, 'msg': 'target host not exist'}
if not arg:
data.pop('arg')
else:
data['arg'] = arg
if tgt != '':
data['tgt_type'] = tgt_type
if salt_async: data['client'] = 'local_async'
data['fun'] = fun
data['tgt'] = tgt
result = self.get_data(self.url, data)
return result
def jobs(self, fun='detail', jid=None):
"""
任務
:param fun: active, detail
:param jod: Job ID
:return: 任務執(zhí)行結(jié)果
"""
data = {'client': 'runner'}
data['fun'] = fun
if fun == detail':
if not jid: return {'success': False, 'msg': 'job id is none'}
data['fun'] = 'jobs.lookup_jid' data['jid'] = jid
else:
return {'success': False, 'msg': 'fun is active or detail'}
result = self.get_data(self.url, data)
return result