Shell(第一天)正則表達式
1)shell是解釋器的總稱,bash只是其中的一種shell
shell編程 bash腳本編程
爲何使用bash?數組
[root@server0 ~]# cat /etc/shellsbash
/bin/shapp
/bin/bashssh
/sbin/nologin編輯器
/usr/bin/shide
/usr/bin/bash工具
/usr/sbin/nologin
/bin/tcsh
/bin/csh
/bin/ksh
2)更改使用某一個解釋器 usermod -s
useradd -s /user/bi/bin/sh
/bin/kshn/ksh nb
su - nb
默認歷史記錄1000條
history -c //清空本身的歷史命令
保存位置:/家目錄/.bash_history
配置文件:/etc/profile
重定向輸入 < 將文本輸入來源由鍵盤改成指定文件
重定向輸出 > 將命令行的正常執行輸出保存到文件,而不是顯示在屏幕
重定向輸出 >> 追加
重定向錯誤 2>
重定向錯誤 2>>追加
混合重定向 &> 不管錯誤正確都覆蓋到一個文件中
[root@server0 ~]# ls /etc/hosts nofile >log1 2>log2
#將一個存在的文件和不存在的文件 正確的導入log1,錯誤的導入log2
收發郵件的兩種方法
echo hello | mail -s hello root
mail -s hello root < mail.txt //須要具有一個文件
1)變量賦值
[root@desktop0 ~]# a=11
[root@desktop0 ~]# b=22
引用變量$a $b
[root@desktop0 ~]# echo $ab #查看變量
輸出11b
[root@desktop0 ~]# echo ${a}${b} #注意括號
輸出1122
2)取消變量:unset
3)存儲類型變量:整數型,浮點型。。。
4)使用類型:環境變量,位置變量,預約義變量,自定義
5)環境變量 配置文件/etc/profile ~/.bash_profile
常見的環境變量:PWD、PATH、USER、LOGNAME、UID、
SHELL、HOME、PS一、PS2
PS1=XX#
6)預約義變量
$0 //當前所在進程或腳本名
$* //全部位置變量的值
$# //已加載的位置變量的個數
$? //上一條命令的輸出狀態,0表示正常,1或其餘表示異常
$! //後臺運行的最後一個進程
7)位置變量 在執行腳本時提供的命令行參數
$1 //第一個變量
$2 //第二個變量
env //查看當前系統的全部變量
set //列出全部變量
8)腳本的執行方式:
當沒有加x權限的狀況
sh 腳本文件路徑
source 腳本文件路徑
. 腳本文件路徑
9)雙引:使用雙引號能夠界定一個完整的字符串
touch a b //建立兩個文件
touch 「a b」 //建立一個文件
單引:一個完整的字符串,而且屏蔽特殊符號
a=11
echo 「$a」 //輸出a的值
echo ‘$a’ //輸出$a
echo 「ab」 == echo ‘ab’
echo 「$a」 != echo ‘$a’
反引:` ` 和$效果同樣
將命令的執行輸出做爲變量值
[root@desktop0 ~]# echo $(ls) #注意括號
1.sh anaconda-ks.cfg
[root@desktop0 ~]# echo `ls`
1.sh anaconda-ks.cfg
案例:每週五備份/etc/log
0 4 * * 5 tar -zcf /root/log.tar.gz /etc/log
//這樣容易形成每週五將原有的數據覆蓋
0 4 * * 5 tar -zcf /root/log.`date +%F`.tar.gz /etc/log
//這樣就起到了每週五不會覆蓋原有的數據
10)read 標準輸入取值
格式:read [-p 提示信息] 變量名
11)stty -echo //關閉回顯
stty echo //恢復
局部變量 a=11
全局變量 export a=11
1)expr命令
乘法操做應採用 \* 轉義,避免被做爲Shell通配符;參與運算的整數值與運算操做符之間須要以空格分開,引用變量時必須加$符號
X=1234
expr $X + 78
2)使用$[]或$(())表達式
乘法操做*無需轉義,運算符兩側能夠無空格;引用變量可省略 $ 符號([]內不須要在變量前加$);計算結果替換表達式自己,可結合echo命令輸出。
[root@server0 ~]# x=1234
[root@server0 ~]# echo $[x+78] #注意和輸出變量{}的區分
1312
[root@server0 ~]# echo $x+78
1234+78
3)let命令
expr或$[]、$(())方式只進行運算,並不會改變變量的值;而let命令能夠直接對變量值作運算再保存新的值。所以變量X=1234,在執行let運算後的值會變動;另 外,let運算操做並不顯示結果,可是能夠結合echo命令來查看
[root@server0 ~]# x=1234
[root@server0 ~]# let y=x+22
[root@server0 ~]# echo $y
1256
[root@server0 ~]# x=7
[root@server0 ~]# let x*3 //不能這樣寫
[root@server0 ~]# echo $x //值爲7
[root@server0 ~]# let x*=3
[root@server0 ~]# echo $x //值爲21
1)bc交互式運算
先執行bc命令進入交互環境,而後再輸入須要計算的表達式。
scale=2 //小數點後面留出來2位數字
2)bc非交互式運算
將須要運算的表達式經過管道操做交給bc運算
[root@server0 ~]# echo 'scale=4;12.34+5.6789' | bc
18.0189
能夠進行數值比較
[root@server0 ~]# echo "2>3" | bc
0 //2是否大於3 輸出0錯誤
[root@server0 ~]# echo "3>2" | bc
1 //2是否大於3 輸出1正確
和$?相反
1)字符串測試
使用「test 表達式」或者[ 表達式 ]均可以,表達式兩邊至少要留一個空格。
== 比較兩個字符串是否相同
[root@server0 ~]# [ $USER == "root" ] // [ ] 內雙引號有無均可以,[ 後面須要有空格
[root@server0 ~]# [ $USER != "root" ]
[root@server0 ~]# echo $? //查看上一條命令的結果0爲對,非0爲錯
-z 檢查變量的值是否未設置(空值)
[root@server0 ~]# [ -z $dachui ]
[root@server0 ~]# echo $?
0
2)整數值比較
-eq -ne -ge -le -gt -lt
3)文件狀態
-e -d -f -r -w -x
4)多個條件/操做的邏輯組合
&& || ;
A && B //執行A,當A成功後執行B
A || B //執行A,當A失敗後執行B
A ;B //執行A ,執行B
-x 判斷對象是否具備可執行權限(特殊)
[root@svr5 ~]# chmod 644 /1.sh
[root@server0 ~]# chmod -x 1.sh
[root@server0 ~]# ./1.sh
-bash: ./1.sh: 權限不夠
//沒有x權限root也執行不了
#判斷有沒有裝包,有沒有起服務的腳本
#!/bin/bash
rpm -q httpd
if [ $? -ne 0 ];then
yum -y install httpd &> /dev/null
fi
systemctl status httpd
if [ $? -ne 0 ];then
systemctl restart httpd
systemctl status httpd
echo $?
fi
Ping -c2 IP //count ping的次數
Ping -i0.1 IP //每次間隔的時間
echo {1..5}
seq 5
都是輸出1到5
2 for
for i in 條件
do
done
[root@server0 ~]# for i in {1..5}
[root@server0 ~]# for i in `seq 5`
while 條件 (while : //死循環)
do
done
for 和while 的區別:
for 循環有限制 while 循環無限制
[root@server0 ~]# echo $[2**3]
8
case 變量值 in
模式1)
命令序列1;;
模式2)
命令序列2;;
*)
默認命令序列
esac
case 簡單,功能少
[root@server0 ~]# echo -e "\033[38mOK\033[0m"
[root@server0 ~]# echo -e "\033[34mOK\033[0m"
兩次輸出的OK的顏色不同
-e extend(擴展)
3x表明字體色
4x表明背景色
0x表明樣式
三個能夠寫在一塊兒
格式:
[root@server0 ~]# echo -e "\033[34m:44m:01mOK\033[0m"
中斷[break,continue,exit]
1)break結束整個循環
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && break
echo $i
done
echo OK
運行結果:1 2 OK
2)continue結束本次循環,跳到下一個循環
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && continue
echo $i
done
echo OK
運行結果:1 2 4 5 OK
3)exit結束腳本
#!/bin/bash
for i in {1..5}
do
[ $i -eq 3 ] && exit
echo $i
done
echo OK
運行結果:1 2
Shell(第四天)
1)${var:起始位置:長度} //從第0位開始
[root@server0 ~]# X=135556684456
[root@server0 ~]# echo ${#X} #獲取變量x有多少位
12
//統計X的長度
[root@server0 ~]# echo ${X:0:4}
1355
2)expr substr "$var" 起始位置 長度 #該方法起始從1開始
[root@server0 ~]# expr substr $X 2 4
3)echo $var | cut -b 起始位置-結束位置 #該方法起始從1開始
[root@server0 ~]# echo $X | cut -b 4-6
1)只替換第1個子串
格式:${var/old/new}
[root@server0 ~]# x=123456123456
[root@server0 ~]# echo ${x/3/*}
12*456123456
2)替換所有子串
格式:${var//old/new}
[root@server0 ~]# echo ${x//3/*}
12*45612*456
(替換不影響x的值,只會影響輸出的顯示效果)
1)從左向右,最短匹配刪除(掐頭)
格式:${變量名#*關鍵詞}
刪除從左側第1個字符到最近的關鍵詞的部分,* 做通配符理解:
[root@server0 ~]# x='root:x:0:0:root:/root:/bin/bash'
[root@server0 ~]# echo ${x#*:} //只刪除最近:以前的
x:0:0:root:/root:/bin/bash
2)從左向右,最長匹配刪除
[root@server0 ~]# echo ${x##*:} //刪除到:以前全部的
/bin/bash
3)從右向左,最短匹配刪除(去尾)
[root@server0 ~]# echo ${x%:*}
root:x:0:0:root:/root
4)從右向左,最長匹配刪除
[root@server0 ~]# echo ${x%%:*}
root
經過${var:-word}判斷變量是否存在,決定是否給變量賦初始值
若變量var已存在且非Null,則返回 $var 的值;不然返回字串「word」,原變量var的值不受影響。
[root@server0 ~]# echo ${NB:-123} //var值不存在
123
[root@server0 ~]# NB=hehe //var值存在
[root@server0 ~]# echo ${NB:-123} //輸出原變量的值
hehe
總體賦值的格式爲「數組名=(值1 值2 值3 .. ..)」
[root@server0 ~]# x=(11 22 33 44 55 66)
[root@server0 ~]# echo ${x[0]}
也能夠直接爲單個數組元素賦值,格式爲「數組名[下標]=值」
[root@server0 ~]# x[0]=1
[root@server0 ~]# x[1]=2
[root@server0 ~]# x[2]=3
變量名裏不能再包含變量(例如x$i)
查看數組內的內容:
[root@server0 ~]# echo ${x[*]}
expect能夠爲交互式過程(好比FTP、SSH等登陸過程)自動輸送預先準備的文本或指令,而無需人工干預。觸發的依據是預期會出現的特徵提示文本。
yum -y install expect
#!/bin/bash
ip=176.19.1.65
expect << EOF (開頭結尾保持一致)
spawn ssh root@$ip //spawn對屏幕監控
expect "password" {send "Taren1\n"} //當屏幕出現password發送密碼
expect "#" {send "touch /root/a.txt\n"}
expect "#" {send "exit\n"}
EOF
3個問題
1)continue的問題
rm -rf /root/.ssh/known_hosts //刪除第一登陸輸入保存yes的文件
2)timeout (在遠程鏈接以前等待一會)
man expect //
set timeout 30 //須要放在遠程命令以前
3)最後一行不執行 (上邊腳本的expect "#" {send "exit\n"})
(需加雙引號)
[]集合查找的是單個字符
* :例如 grep 「a*」 a.txt //匹配a出現的(a,aa,aaa)
. 匹配任意單個字符,能夠取出非空行
.* 表明匹配任意全部 空行,非空行一塊兒取出
a\{2,m\} m能夠不寫 //匹配a出現2到m次 m無限制
使用 \> 匹配單詞右邊界
\(\) abcabcjklkjl
grep ‘(abc)\1(jkl)\2’ a.txt
最開始和最後一個字母對調
[root@server0 ~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' 1.txt
八、擴展正則
(簡化基本,擴展新的)
? 前面字符出現0或者1次
+ 前面字符出現1次或屢次
() 總體 (abc)+ abc abcabc ...
\b 單詞邊界,精確過濾
[root@room8pc205 桌面]# grep 'the' 1.txt #不管the在哪都匹配
hello the world
theapple is great
tast atheorang
[root@room8pc205 桌面]# grep '\bthe' 1.txt #只匹配the前沒有字符
hello the world
theapple is great
[root@room8pc205 桌面]# grep '\bthe\b' 1.txt
hello the world
擴展正則:簡單,兼容性差(並非)
基本正則:複雜,兼容性強(全部軟件都支持)
Shell(第五天)
1)非交互
逐行處理
Vim ——硬盤到內存,一次所有顯示
Sed ——一行到內存的顯示
2)[root@server0 ~]# sed -n '3p' /etc/passwd #顯示第3行
不加-n的時候,會在第三行將第三行重複打印 (-n取消自動打印模式空間)
屏蔽默認輸出
-r, --regexp-extended 在腳本中使用擴展正則表達式 -i 直接修改文件內容
p 顯示(print)
sed -n '3p;5p' /etc/passwd #顯示第3,第5行 多個指令用分隔符
sed -n '3,5p' /etc/passwd #顯示第3到第5行
sed -n '3,+5p' /etc/passwd #顯示第3行以及其後的5行
sed -n 'p;n' /etc/passwd #輸出奇數行,sed自動讀行,給n拒絕
sed -n 'n;p' /etc/passwd #輸出偶數行
sed -n '$=' /etc/passwd #輸出文件的行數 wc -l
sed -n '/834/!p' /etc/passwd #輸出不包括843的行
根據正則相結合使用(不知道行號)
[root@server0 ~]# sed -n '/root/p' /etc/passwd #找出/root並顯示出來
d 刪除(delete)
sed '3,5d' /etc/passwd #刪除3到5行
sed ‘/xml/d’ /etc/passwd #刪除全部包含xml的行(整行刪除)
sed ‘/xml/!d’ /etc/passwd #刪除不包含xml的行
s 替換 (substitution)
sed ‘s/old/new/’ #文件每行第一個old替換爲new
sed ‘3s/old/new/’ #文件第3行第一個old替換爲new
sed ‘s/old/new/g’ #文件全部old替換爲new
sed ‘s/old/new/3’ #文件每行第三個old替換爲new
sed ‘s/old//g #文件全部old替換爲空
sed ‘s/old/&s/g’ #文件全部old替換爲olds
sed 's#/bin/bash#/sbin/sh#' #可使用任何特殊符號做爲分隔符必須3個
sed 's/\/bin\/bash/\/sbin\/sh/' #太複雜
i(insert) a(append) c
sed '2i xxx' 1.txt #在第2行的前面插入xxx
sed '2a xxx' 1.txt #在第2行的後面插入xxx
sed '2c xxx' 1.txt #第2行替換爲xxx (整行替換)
sed '2i xx\nyy' 1.txt #在第2行的前面插入xx和yy
r w h g
sed '1r /etc/hostname' 1.txt #在第一行後加入/etc/hostname的內容
sed 'w /qq.txt' 1.txt #在根下另存爲qq.txt(不用i已經存了)
sed '2H;4G' 1.txt #在第2行復制內容加回車在第4行粘貼第2行內容加回車
sed '2h;4g' 1.txt #在第2行復制內容覆蓋第4行爲第2行的內容
Shell(第六天)
逐行處理 (grep只能整行)
能夠過濾列
格式: awk [選項] ‘條件{指令}’ 文件
條件能夠沒有,表明全部
也能夠沒有指令,打印整行
不能同時沒有條件和指令
df | awk '/\/$/{print $4}' #查看以/結尾的第4列的信息 根的磁盤剩餘
tailf /var/log/secure #查看遠程登陸日誌
用途:監控腳本:
登陸日誌
分區剩餘容量:df
內存剩餘容量:free
CPU負載大於xx: top ,uptime
load average: 0.07, 0.21, 0.21
[1,5,15分鐘的平均負載]
默認使用空格或者tab做爲分割符號
-F 指定分隔符(默認空格或者tab)
awk -F: '{print $1}' /etc/passwd #使用:做爲分隔符
awk -F: '{print $1,$3,$7}' /etc/passwd #打印多列
打印變量:
print $0 #整行
print $1 #第一列
print $2 #第二列
print NR #當前行的行號
print NF #當前行的列號
print $NF #打印最後一列
打印常量:(字符串須要加引號)
awk '{print "dachui"}' /etc/passwd #每一行都出來(只有)dachui
awk -F ":" '{print "第"NR"行""第"NF"列"}' /etc/passwd
awk會逐行處理文本,支持在處理第一行以前作一些準備工做,以及在處理完最後一行以後作一些總結性質的工做。在命令格式上分別體現以下:
行前處理,BEGIN{ } #讀取文件以前,執行1次
逐行處理,{ } #讀取文件過程當中執行,執行n次
行後處理,END{ } #讀取文件以後,執行1次
awk -F: 'BEGIN{print "用戶名\tUID\t家目錄"} {print $1,$3,$6} END{print "總用戶 "NR}' /etc/passwd
awk 'BEGIN{x=2;y=3.3;print x*y}' #不加其它選項做爲運算使用
awk變量能夠不定義,就直接用(默認0)
awk 'BEGIN{x=0} /bash$/{x++} END{print x}' /etc/passwd
awk '/bash$/{x++} END{print x}' /etc/passwd
1)使用正則表達式設置條件
~(模糊)匹配 !~不匹配
awk '/root/' /etc/passwd #對整行匹配
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
awk -F: '$1~/root/' /etc/passwd #匹配第一列是root
root:x:0:0:root:/root:/bin/bash
awk -F: '$7!~/bash$/' /etc/passwd #匹配第7列不是bash結尾的行
2)使用數值/字符串比較設置條件 (字符串須要引號,精確匹配)
== != >= <= > <
awk -F: '$1=="root" /etc/passwd #精確匹配第一列是root的行
3)邏輯測試條件
&&邏輯與
awk -F: '$3>=10 && $3<=20' /etc/passwd
|| 邏輯或
awk -F: '$3==0 || $3==1000' /etc/passwd
4)數學運算
+ - * / % ++ --
seq 200 | awk '$1%7==0 || $1~/7/' #200之內可以整除7而且包含7的
1)if分支結構(雙分支、多分支)
找出多少系統用戶,多少普通用戶
awk -F: '{if ($3>=1000){x++}else{y++}}END{print x,y}' /etc/passwd
找出第一列是M.Tansley而且第六列-1,輸出1,6,7列
awk '{if($1=="M.Tansley")$6-=1;print $1,$6,$7}' awk_exe.txt
2)while循環結構
統計詞頻[文章,日誌,文件]
例:統計/etc/passwd中的root出現的次數
[root@svr5 ~]# awk -F [:/] \
'BEGIN{j=0}\
{i=1}{while(i<=NF){if($i~/root/){j++};i++}}\
END{print j}' /etc/passwd
4
awk -F : ‘{i=1;while(i<=NF){if($i~/root/){j++};i++}}
END{print j}’ /etc/passwd
3)break、continue等其餘控制語句
ab -c 100 -n 10000 http://172.25.0.11/ #模擬100我的同時訪問網站,點擊頁面1000次。IP後必須寫/
拒絕服務***(DOS***)
例:提取IP地址及訪問量
awk '{A[$1]++} #統計第一列的IP
END{for(i in A){print i,A[i]}}' #對每一個IP循環獲得每一個IP的次數
/var/log/httpd/access_log |
awk '$2>=500{print $1}' #找出訪問次數大於500的IP
例:寫一個進度條腳本
#!/bin/bash
jindu(){
while :
do
echo -n '#'
sleep 0.3
done
}
jindu &
cp -r $1 $2
kill $!