linux和bash實戰
阿新 • • 發佈:2021-01-02
指令碼與函式
花括號括起來的一段shell命令
#錯誤寫法
[[email protected] ~]$ cpu_mem(){top -b -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}'; }
-bash: 未預期的符號 `{top' 附近有語法錯誤
#錯誤寫法
[[email protected] ~]$ cpu_mem(){ top -b -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}' }
>
#正確的單行寫法
cpu_mem(){ top -b -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}'; }
#多行寫法
cpu_mem(){
top -b -n 1 -d 1 | grep -i aliyundun$ | awk '{print $9,$10}';
}
#引數化
cpu_mem(){ top -b -n 1 -d 1 | grep -i "$1" | awk '{print $9,$10}';}
bash_profile作用
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
export PATH
cpu_mem ()
{
top -b -n 1 -d 1 | grep --color=auto -i "$1" | awk '{print $9,$10}'
}
- .bash_profile 每次shell啟動都會預設載入
- PATH變數是預設找命令的地址 /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
三劍客演練
分類統計
[[email protected] ~]$ echo '
a 1
a 2
a 3
b 4
b 5
b 6
' | awk '{d[$1]+=$2}END{for(k in d) print k,d[k]}'
0
a 6
b 15
[[email protected] ~]$ echo '
a 1
a 2
a 3
b 4
b 5
b 6
' | awk '{print "d["$1"]+="$2}'
d[]+=
d[a]+=1
d[a]+=2
d[a]+=3
d[b]+=4
d[b]+=5
d[b]+=6
d[]+=
[[email protected] ~]$
awk與python的對比
def test_awk():
# awk預設詞典不用初始化
time = {}
count = {}
# awk把每行拆分為一個個的記錄,其實就是包含每條記錄的列表
# awk通過$1 $2把每個記錄又拆分成了小列表
data = [
["a", 1],
["a", 2],
["a", 3],
["b", 4],
["b", 5],
["b", 6]
]
for record in data:
# 對應$1
k1 = record[0]
# 對應$2
k2 = record[1]
# awk預設不用做初始化
if k1 not in time:
time[k1] = 0
# 等價於 d[$1] += $2
time[k1] += k2
if k1 not in count:
count[k1] = 0
count[k1] += 1
# 對應 for(k in d) print k,d[k] 寫法基本一致
for k in time:
print(f"k={k}, avg={time[k] / count[k]}")
精簡版python程式碼
def test_awk_mini():
time, count = {}, {}
data = [
["a", 1],
["a", 2],
["a", 3],
["b", 4],
["b", 5],
["b", 6]
]
for record in data:
time.setdefault(record[0], 0) # todo: 型別判斷 string預設為"" int預設為0
time[record[0]] += record[1]
count.setdefault(record[0], 0)
count[record[0]] += 1
# 對應 for(k in d) print k,d[k] 寫法基本一致
for k in time:
print(f"k={k}, avg={time[k] / count[k]}")
awk程式碼
# echo '
# a 1
# a 2
# a 3
# b 4
# b 5
# b 6
# ' | awk '{d[$1]+=$2}END{for(k in d) print k,d[k]}'
找出狀態碼第9位為404和500的錯誤日誌,
less nginx.log | awk '$9=="404" || $9 == "500"'
awk '$9=="404" || $9 == "500"' nginx.log|less
awk '$9~/404|500/' nginx.log | less
正則表示式 : awk '$9=="404" || $9 == "500" {print $9}' nginx.log
不斷計數: awk '$9~/404|500/{t+=1}END{print t}' nginx.log
awk和sed、grep等都可以跟檔名,使用正則時,awk可直接跟正則表示式,但是sed和grep要加-E
並統計錯誤日誌的行數
less nginx.log | awk '{print $9}'| grep -E '500|404' | wc -l
less nginx.log | awk '$9=="404" || $9 == "500"' | wc -l
正則表示式 : awk '$9=="404" || $9 == "500" {print $9}' nginx.log
不斷計數: awk '$9~/404|500/{t+=1}END{print t}' nginx.log
取出最大的響應時間 max_response_time()
max_response_time ()
{
less nginx.log | awk '{print $(NF-1)}' | sort -nr | head -1
}
取出top3的響應時間,並打印出對應的url max_response_time_and_url()
max_response_time_and_url ()
{
less ~/nginx.log | awk '{print $(NF-1), $7}' | sort -rn | head -3
}
取出全部請求的平均響應時間 avg_response_time()
avg_response_time ()
{
less nginx.log | awk '{sum+=$(NF-1)}END{print sum/NR}'
}
取出所有相同url請求的平均響應時間,並且按照響應時間排序取出top 3 avg_response_time_by_url()
avg_response_time_by_url ()
{
less nginx.log | awk '{time[$7]+=$(NF-1); count[$7]+=1;}END{for(k in time) print time[k]/count[k], k}' | sort -nr | head -3
}
統計每個url的頂層路由地址所對應的qps qps_by_route()
比如
[05/Dec/2018:00:00:01 +0000] /topics/17112
[05/Dec/2018:00:00:02 +0000] /topics?page=63
計算/topics的平均qps 每秒多少次請求,列印平均qps最高的top5的頂級路由
/topics 100
/cable 80
less nginx.log |
awk '{print $4,$7}' |
sed 's#[?!].*##' |
sed -E 's#([^ ]*) *(/[^/]*).*#\1:\2#' |
sort |
awk -F: '
{cur=($3*60+$4);}
NR==1{min=cur; max=cur;}
NR>1{
count[$NF]+=1;
if(cur<min) min=cur;
if(cur>max) max=cur;
}
END{
for(k in count) print k,count[k]/(max-min+1)}
' |
sort -k2 -nr | head -5
程序與網路
每隔1s統計下aliyundun的2個程序的cpu與mem,分類彙總下10s內的平均cpu與響應時間 avg_cpu_mem_py_process()
top -b -d 1 -n 10 | grep -i aliyundun | awk '{cpu[$NF]+=$(NF-3);mem[$NF]+=$(NF-2);count[$NF]+=1}END{for(k in cpu) print k, cpu[k]/count[k], mem[k]/count[k]}'
統計當前伺服器上每個監聽埠對應的網路狀態的數量 connections_summary()
netstat -tn | sed 1,2d | awk '{print $4, $NF}' | awk -F: '{print $NF}' | sort | uniq -c
微信朋友圈
friend() {
while true; do
#獲取介面,提取暱稱和朋友圈內容
adb shell 'uiautomator dump && cat /sdcard/window_dump.xml' |
sed 's#><#>|<#g' |
awk 'BEGIN{RS="|"}{print $0}' |
awk -F\" '
BEGIN{OFS="\t"}
/e3x/{name=$4}
/b_e/{msg=$4;print name,"|",msg}
'
#取出大概的滑動距離
distance=$(
adb shell wm size |
awk -F' |x' '
{
width=$(NF-1);
height=$NF;
print width*0.5, height*0.8, width*0.5, height*0.2}'
)
#利用input直接劃屏
adb shell input swipe $distance
done
}