01 | Linux系統(tǒng)和Shell環(huán)境準備
運行shell
test.sh
#!/bin/bash
echo "hello"
運行腳本
方式一:
chmod+x ./test.sh
./test.sh
方式二:
/bin/sh test.sh 若以此方式運行捺信,test.sh(shell腳本)中的 #!/bin/bash則不起作用
02 | Linux常用命令(文件/網(wǎng)絡/性能)
文件
常用命令
ls | cd | pwd | mkdir | rmdir | cp | rm | mv-
文件屬性
修改文件屬性
- 字母模式
chmod a+rwx file # 所有人 賦予 file1 讀末荐、寫、執(zhí)行 的權限
chmod a-rwx file # 所有人 取消 file1 讀僻肖、寫、執(zhí)行 的權限
chmod u+r file # 只給 file1的擁有者 賦予 讀 的權限
chmod g-w file # 只取消 同組人 寫 的權限
chmod o+x file # 只給 其他人 賦予 file1 執(zhí)行 的權限
chmod ug+x,o-w file # 給文件擁有者和同組人賦予執(zhí)行權限区赵,取消其他人的寫權限
- 數(shù)字模式
chmod 777 file 等價于 chmod a+rwx file1 -rwxrwxrwx
chmod 765 file 等價于 chmod u+rwx,g+rw,o+rx file1 -rwxrw-r-x
chmod 432 file 等價于 chmod u+r,g+wx,o+w -r---wx-w-
網(wǎng)絡
ping
1.-c ping的次數(shù)
2.-l 每次ping的時間間隔netstat 打印Linux網(wǎng)絡系統(tǒng)的狀態(tài)信息
1.-t 列出所有tcp
2.-u 列出所有udp
3.-l 只顯示監(jiān)聽端口
4.-n 拒絕顯示別名郁副,能顯示數(shù)字的全部轉(zhuǎn)化成數(shù)字(重要)
5.-p 顯示進程的pid和名字練習
netstat -apn | grep ssh 查看指定程序的端口
netstat -apn | grep ":80" 查看運行在指定端口的進程
性能
- top 持續(xù)監(jiān)視系統(tǒng)性能
- ps 查看進程信息
1.-aux 顯示所有進程,包括用戶是嗜、分組情況
03 | Linux三劍客與管道使用
- 管道“|”:左邊的輸出作為右邊的輸入
正則表達式
舉例
1.\bword\b 找出所有的word單詞,word前后要有空格
2.\bword\b.*\bluck\b 第1個單詞是word挺尾,最后1個單詞是luck鹅搪,中間為任意內(nèi)容
3.0\d{2}-\d{8} 以0開頭+兩個數(shù)字+“-”+8個數(shù)字常用的元字符
符號 | 說明 |
---|---|
. | 匹配換行符以外的任意字符 |
\w | 匹配字母或數(shù)字或下劃線或漢字 |
\s | 匹配任意的空白符 |
\d | 匹配數(shù)字 |
\b | 匹配單詞的開始或結(jié)束 |
^ | 匹配行首 |
$ | 匹配行尾 |
- 常用的限定符
符號 | 說明 |
---|---|
* | 重復零次或更多次 |
+ | 重復1次或更多次 |
? | 重復零次或1次 |
{n} | 重復n次 |
{n,} | 重復n次或更多次遭铺,重復上限或下限 |
{n,m} | 重復n到m次 |
- 實例
1.匹配以字母a開頭的單詞:\ba\w*\b
2.匹配剛好6個字符的單詞:\b\w{6}\b
3.匹配1個或更多連續(xù)的數(shù)字:\d+
4.5到12位QQ號:\d{5,12}
grep
grep [options] pattern [file...]
pattern 可以是正則表達式
- 參數(shù)
1.-v 顯示不被pattern匹配到的行
2.-i 忽略字符大小寫
3.-n 顯示行號
4.-c 統(tǒng)計匹配的行數(shù)
5.-o 僅顯示匹配到的字符串
6.-E 使用ERE丽柿,相當于egrep
sed
流處理器,一次處理一行內(nèi)容
若sed后不加任何參數(shù)掂僵,則只操作模式空間的內(nèi)容航厚,不操作原文件顷歌;若想修改原文件锰蓬,需加參數(shù)-i
-
處理流程
格式
sed [-hn..][-e<script>][-f<script FILE>][FILE]命令解析
1.-h 顯示幫助
2.-n 靜默模式,僅顯示script處理后的結(jié)果
3.-e<script> 以選項中指定的script來處理輸入的文本文件
4.-f<script文件> 以選項中指定的script文件來處理輸入的文本文件常用命令
1.a:新增眯漩; sed -e '4a newline' 芹扭;在第4行后新增1行,內(nèi)容為“newline”
2.c:取代赦抖;sed -e '2,5c number'舱卡;用“number”取代2到5行的內(nèi)容
3.d:刪除;sed -e '2,5d'队萤;刪除2到5行
4.i:插入轮锥;sed -e '2i newline';在第2行前插入1行要尔,內(nèi)容為“newline”
5.p:打由岫拧新娜;sed -n '/root/p';打印與root匹配的行
6.s:取代既绩;sed -e 's/old/new/g'概龄;全局替換,若沒有g則只替換每行的第一個
注:-e可省略練習
sed -i '$a abc\ndef\nghi' file 在文件末尾插入
sed -i '1i abc\ndef\nghi' file 在文件開頭插入
-sed和grep的區(qū)別
1.grep只能查詢
2.sed能夠增刪改查
awk
把文件逐行的讀入饲握,以空格為默認分隔符將每行切片私杜,切開的部分再進行后續(xù)處理
-
處理流程
格式
awk 'pattern + action' [FILE]常用參數(shù)
1.BEGIN 處理文本之前要執(zhí)行的操作
2.END 處理文本之后要執(zhí)行的操作
3.FS(field separator) 輸入字段分隔符,默認空格救欧,相當于-F
4.NF(number fields) 當前輸入記錄的字段數(shù)(列數(shù))
5.NR(number records) 目前為止看到的記錄總數(shù)(行數(shù))
6.OFS 輸出域分隔符(不常用)
7.ORS 輸出記錄分隔符(不常用)
8.RS(record separator) 輸入記錄分隔符衰粹,默認換行符
9.$0
整條記錄
10.$1
表示當前行的第一個字段練習1
1.搜索/etc/passwd有root關鍵字的所有行:awk -F: '/root/{print $0}' /etc/passwd
2.打印/etc/passwd的第2行信息:awk -F: 'NR==2{print $0}' /etc/passwd
練習2
1.使用begin加入標題:awk -F: 'BEGIN {print "BEGIN,BEGIN"}{print $1,$2}' /etc/passwd
2.自定義分割符:echo "123|456|789" | awk 'BEGIN{RS="|"}{print $0}'
04 | Bash編程語法
變量
變量的作用范圍只在當前窗口
規(guī)則
1.命名只能使用英文字母、數(shù)字颜矿、下劃線寄猩,首個字符不能以數(shù)字開頭
2.中間不能有空格,可以使用下劃線
3.不能使用標點符號
4.不能使用bash里的關鍵字(可用help命令查看保留關鍵字)定義與使用
your_name="abc"
echo $your_name只讀變量(不能修改和刪除)
a="123"
readonly a
若想刪除只讀變量骑疆,把窗口關閉即可刪除變量(不能刪除只讀變量)
unset variable_name變量類型
1.字符串:your_name="timothy"
2.拼接字符串:greeting="hello,"$your_name""
3.數(shù)組:array_name=(value0 value1 value2 value3)
4.取數(shù)組:value=${array_name[n]}
5.單獨賦值:array_name[0]=value0
6.獲取數(shù)組長度:${#array_name[*]}
練習
數(shù)組初始化
array=(a b c d e)
echo ${array[0]}
echo ${array[@]} 打印所有元素
echo ${array[*]} 同上
數(shù)組單個定義
array[0]=a
array[2]=c
echo ${array[*]}
if
- 格式
if condition
then
command1
command2
...
commandN
fi
注意
1.if [ a==1 ]田篇;若判斷條件是雙等號,可使用單中括號
2.if [[ a>1 ]]箍铭;若判斷條件是大于或小于時泊柬,要用雙中括號;若想使用單中括號诈火,需用-gt兽赁、-lt,如if [ a -gt 1]
3.中括號左右必須有空格冷守,不能寫成if[a==1]運算符
符號 | 解釋 |
---|---|
-gt | greater than |
-lt | less than |
-ge | greater or equal |
-le | less or equal |
-eq | equal |
-ne | not equal |
- 練習
比較兩個變量的大小并輸出不同的值
if [ $a -eq $b ];then echo "equal"; elif [ $a -lt $b ];then echo "small";elif [ $a -gt $b ];then echo "big"; fi
for
- 格式
for var in item1 item2 ... itemN
do
command1
command2
...
commandN
done
- 練習
循環(huán)讀取文件內(nèi)容并輸出
for i in ${cat test.txt};do echo "$i";done
while
- 定義
while condition
do
command
done
- 例子
int=1
while(( $int<=5 ))
do
echo $int
let "int++"
done
- 練習
循環(huán)讀取文件內(nèi)容并輸出
while read line;do echo $line;done<test.txt
05 | Bash腳本編寫
read命令
概要
1.read命令是用于從終端或文件中讀取輸入的內(nèi)部命令
2.讀取整行輸入
3.每行末尾的換行符不被讀入使用
1.讀取標準輸入內(nèi)容并賦值給變量:read var
2.讀取多個標準輸入內(nèi)容:read var1 var2 var3
3.不指定標量(默認賦值給REPLY):read練習
read a
123
echo $a
read a b c
123 456 789
echo $a $b $c
read
012
echo $REPLY
腳本參數(shù)傳遞
1.$0
腳本名稱
2.$1~$n
獲取參數(shù)
3.$#
傳遞到腳本的參數(shù)個數(shù)
4.$$
腳本運行的當前進程ID號
5.$*
顯示所有的參數(shù)
6.$?
顯示最后命令的退出狀態(tài)刀崖。0表示沒有錯誤,其他任何值表明有錯誤
- 練習
test.sh
#!/bin/bash
echo "文件名:"$0
echo "入?yún)€數(shù):"$#
echo "所有入?yún)ⅲ?$*
echo "第1拍摇、2亮钦、3個入?yún)ⅲ?$1 $2 $3
echo "退出狀態(tài):"$?
運行test.sh
chmod u+x test.sh
bash test.sh 1 2 3
基本運算
1.加法 `expr $a + $b`
2.減法 `expr $a - $b`
3.乘法 `expr $a \* $b`
4.除法 `expr $b / $a`
5.取余 `expr $a % $b`
6.賦值 a=$b
7.相等 [ $a == $b ]
8.不相等 [ $a != $b ]
bash與目錄命令
創(chuàng)建目錄并生成文件
mkdir test
cd test
echo "hello" > test.txt
ls
bash與內(nèi)存
統(tǒng)計內(nèi)存使用
for i in `ps aux | awk '{print $6}' | grep -v 'RSS'`
do
echo `expr $i / 1024`
done
06 | Nginx日志分析
shell命令中單引號和雙引號的區(qū)別:單引號里內(nèi)容不轉(zhuǎn)義,雙引號里的內(nèi)容會轉(zhuǎn)義充活,舉例說明:
a=123
echo '$a' 輸出$a蜂莉,$a未轉(zhuǎn)換
echo "$a" 輸出123,$a轉(zhuǎn)換為變量值
grep只支持基本正則混卵,不支持擴展正則映穗,要使用“|”需用egrep,舉例說明:
egrep "ab[c|cc]" test.sh
輸出abc abcc
- 出現(xiàn)次數(shù)最多的ip個數(shù)
awk '{print $1}' nginx.log | sort | uniq -c | sort -nr | head -3
grep -o '^[0-9]*.[0-9]*.[0-9]*.[0-9]*' nginx.log | sort | uniq -c | sort -nr | head -3
- 替換
grep "/topics/" nginx.log | sed 's#/topics/[0-9]*#/topics/number#g'
- 將ip地址橫向打印
awk '{print $1}' nginx.log | sed ':1;N;s/\n/|/g;t1'
N 將下一行讀取到模式空間
:1 標記
t1 t1前的命令執(zhí)行成功幕随,就跳轉(zhuǎn)到標記1
反復執(zhí)行":1"和"t1"之間的命令
07 | Linux性能統(tǒng)計分析
命令說明
命令 | 全稱 | 說明 |
---|---|---|
mpstat | Multiprocessor Statistics | 多處理器狀態(tài) |
vmstat | virtual memory statistics | 虛擬內(nèi)存狀態(tài) |
iostat | input output statistics | 輸入輸出狀態(tài) |
uptime
15:52:31 up 4 days, 21:33, 1 user, load average: 0.00, 0.01, 0.05
當前時間 總開機時間 當前用戶 負載(1分蚁滋,5分,15分)
負載
特定時間間隔內(nèi)運行隊列中的平均進程數(shù)。進程滿足以下條件則位于運行隊列中:
1.未等待I/O操作的結(jié)果
2.未主動進入等待狀態(tài)(未調(diào)用wait)
3.未被停止(等待終止)
一般來說辕录,每個CPU內(nèi)核當前活動進程數(shù)不大于3澄阳,則表示系統(tǒng)運行表現(xiàn)良好。若是多核則需要累加踏拜,即4核cpu<12
dmesg | tail -20
打印系統(tǒng)日志
vmstat
- 虛擬內(nèi)存:磁盤的部分空間被當做內(nèi)存使用
- cache:CPU和內(nèi)存之間的高速緩沖存儲器
- buffer:內(nèi)存和磁盤之間的緩沖器
- 分頁:將磁盤空間轉(zhuǎn)換為虛擬內(nèi)存的技術
- 字段說明
procs(進程):
1.r:運行隊列中進程數(shù)量碎赢,可判斷是否需要增加CPU(長期大于1)
2.b:等待IO的進程數(shù)量
memory(內(nèi)存):
1.swpd:使用虛擬內(nèi)存大小,此值越大說明物理內(nèi)存已不夠用
2.free:空閑物理內(nèi)存大小
3.buff:用作緩沖的內(nèi)存大小
4.cache:用作緩存的內(nèi)存大小
CPU:
1.us:用戶進程執(zhí)行時間
2.sy:系統(tǒng)進程執(zhí)行時間
3.id:空閑時間(包括IO等待時間)速梗,中央處理器的空閑時間
4.wa:等待IO時間
mpstat
語法
mpstat [-P ] [internal [count]]
1.-P 指定CPU
2.internal:相鄰兩次采樣的間隔時間
3.count:采樣次數(shù)-
參數(shù)
參數(shù) | 說明 |
---|---|
%usr | 用戶級(應用程序)執(zhí)行時發(fā)生的CPU利用率百分比 |
%nice | 優(yōu)先級較高的用戶級別執(zhí)行時發(fā)生的CPU利用率百分比 |
%sys | 系統(tǒng)級(內(nèi)核)執(zhí)行時發(fā)生的CPU利用率百分比 |
%iowait | 系統(tǒng)有未完成的磁盤I / O請求時一個或多個CPU空閑的時間百分比 |
%irq | 一個或多個CPU服務硬件中斷所花費的時間百分比 |
%soft | 一個或多個CPU服務軟件中斷所花費的時間百分比 |
%idle | 一個或多個CPU空閑且系統(tǒng)沒有未完成的磁盤I / O請求的時間百分比 |
- 理解iowait
CPU空閑時間處理io請求的占比
CPU可以并行處理io請求
其他命令
- pidstat
- iostat
- free -m
- top
1.%CPU是CPU每個核占比的累加
08 | 三劍客實戰(zhàn)抽獎程序腳本
- 抽獎實現(xiàn)1:有空白
#!/bin/bash
rand() {
seeds=`while read line; do echo ${line// /..}; done < wx.txt`
while [[ $count != 1 ]];do
seeds=`for seed in $seeds;do (($RANDOM%2==0)) && echo $seed; done` # seeds只有1個元素時肮塞,$RANDOM%==1,此時會輸出空白
count=`echo "$seeds" | wc -l`
done
echo $seeds
}
rand
- 抽獎實現(xiàn)2:無空白
#!/bin/bash
rand() {
local count
local seeds
count=0
seeds=`while read line; do echo ${line// /..}; done < wx.txt`
while [[ $count != 1 ]];do
seeds=`for seed in $seeds;do (($RANDOM%2==0)) && echo $seed; done`
count=`echo "$seeds" | wc -l`
done
if [[ $seeds == "" ]];then
rand # 這里用到了遞歸
fi
if [[ $seeds != "" ]];then
echo $seeds
fi
}
while true;do
rand
sleep 1s
done
- 抽獎實現(xiàn)3:去重
rand() {
local seeds
local count
count=0
seeds=`while read line;do echo ${line// /..}; done<test.txt`
while [[ $count != 1 ]];do
seeds=`for seed in $seeds;do (($RANDOM%2==0)) && echo $seed;done`
count=`echo "$seeds" | wc -l`
done
if [[ $seeds == "" ]];then
rand
fi
if [[ $seeds != "" ]];then
echo $seeds
fi
}
res() {
for i in `eval echo {1..$1}`;do
tmp=`rand`
while [[ `is_repeat $tmp` == 0 ]];do
tmp=`rand`
done
arrs[$i]=$tmp
done
echo ${arrs[@]}
}
is_repeat() {
for arr in ${arrs[@]};do
if [[ $arr == $1 ]];then
#此處需要有echo姻锁,因為子進程只能捕獲echo的輸出枕赵,不能捕獲return的值
echo 0
return 0
fi
done
#輸出1的邏輯在這里,因為需要遍歷完整的數(shù)組后位隶,才能輸出1
echo 1
}
res $1
其他
1.echo $var
把所有行合并成1行輸出
2.echo "$var"
按原格式輸出設置vim編輯器一直顯示行號
vim ~/.vimrc
set nu