一、編程基礎:
shell腳本是包含一些命令或聲明,并符合一定格式的文本文件
shell腳本的用途有:
-
自動化常用命令
-
執行系統管理和故障排除
-
創建簡單的應用程序
-
處理文本或文件
1) 第一步:使用文本編輯器來創建文本文件 script.sh 并編寫內容
格式要求:首行shebang 指明所要使用的shell類型
#!/bin/bash #!/usr/bin/python #!/usr/bin/perl
結合命令、變量、表達式、語句等編寫腳本內容
“#”號開頭的行為注釋行
#echo something echo "test txte"
2) 第二步:運行腳本
給予執行權限,在命令行上指定腳本的絕對或相對路徑
]#chmod +x script.sh ]#./script.sh
直接運行解釋器,將腳本作為解釋器程序的參數運行
]#bash script.sh
#bash:調試執行腳本
-n 簡單檢查腳本語法錯誤
-x 調試執行,顯示腳本運行過程
二、變量:
變量類型:
1)本地變量:作用域僅為當前shell進程
變量的定義:
用戶定義的變量有字母數字及下劃線組成,
變量名的第一個字符不能為數字.
變量名是大小寫敏感的
變量的引用:
${name},$name
" ": 雙引號 變量名會替換為其值
' ' :單引號 變量名不會替換
查看變量:set
撤銷變量:unset name
2)環境變量:作用域為當前變量及其子進程 對其他登錄用戶無效
變量賦值:
export name=value
declare -x name=value
bash內嵌了很多環境變量(一般為全大寫),用于定義bash工作環境
PATH,HISTFILE,HISTSIZE,SHELL,HOME,UID,OLDPWD
查看環境變量:export;declare -x;printenv;env
撤銷環境變量:unset name
3)局部變量:作用域為某代碼片段 函數上下文
4)只讀變量(常量)
declare -r name
readonly name
只讀變量無法重新設定,不支持撤銷,當前shell終止后撤銷
5)特殊變量
$0 腳本文件路徑本身 basename
$#:參數個數
$*:所有參數 "chen he zhao" 所有參數合并為單個字符串
$@:所有參數 "chen" "he" "zhao"
位置變量:
向腳本傳遞位置參數變量:
scrip.sh argu1 argu2
對應
$1,$2…${10},${11}…
輪替:
shift# 去掉前#個參數 即${#+1}變成$1
數據類型:字符型,數值型
三、數值運算:
算術運算: + – * / % ^ *乘法有時需要轉義
let var=expr
$[expr]
$((expr))
$(expr argu1 argu2 argu3
增強型賦值:
let
i+=# :i=$i+#
i-=
i*=
i/=
i%=
自增/自減:
let VAR=$($VAR+1)
let VAR+=1
let VAR++
—
]#i=1 ]#let i++ ]#echo $i ]#2 ]#let i+=2 ]#echo $i ]#4 ]#expr 3 + 4]#expr 3 \* 4]#echo 3*4|bc
四、邏輯運算:
運算數:真(true,yes,on,1)
假(false,no,off,0)
1.與
1 && 1 = 1
1 && 0 = 0
0 && 1 = 0
0 && 0 = 0
2.或
1 || 1 = 1
1 || 0 = 1
0 || 1 = 1
0 || 0 = 0
3.非
! 1 = 0
! 0 = 1
4.異或
真真 假
真假 真
1)CMD1 && CMD2 如果真…就…
CMD1為假 則CMD2不運行
CMD1為真 則CMD2運行
2)CMD1 || CMD2 如果假…就…
CMD1為真 則CMD2不運行
CMD1為假 則CMD2運行
五、bash測試類型:
測試表達式:
test EXPRESSION
[ EXPRESSION ] 表達式兩端須有空格
[[ EXPRESSION ]]
1.數值測試: [ $num1 -## $num2 ] 整數測試!
-eq:等于
-ne:不等于
-gt:大于
-ge:大于等于
-lt:小于
-le:小于等于
]#[ 5 -gt 4 ]&&echo 0 ]#0
2.字符串測試: [[ "CHAR" # "CHAR" ]] ASCLL碼比較
==:是否等于
>: 大于 ascll 編碼
<: 小于
!=:不等于
=~:左側字符串 是否能夠被右側 模式匹配
* -z "STRING":判斷變量是否為空;空位真,不空為假
-n "STRING":判斷是否不空 空為假,不空為真
]#[[ root =~ r.*t ]]&&echo 0 ]#0
3.文件測試:
存在性測試:
-a FILE
-e FILE
存在為真
文件類型測試:[ -# /PATH/FILE ]
-b 存在且為 塊設備
-c 存在且為 字符設備文件
-d 存在且為 目錄
-f 存在且為 普通文件
-p 存在且為 管道文件
-S 存在且為 套接字文件
-h|L 存在且為 符號鏈接文件
]#[ -d /etc ] && echo 0
]#0
4.文件權限測試: 以用戶 實際權限; root用戶存在特權
000 但對root可讀 可寫 不可執行
-r 存在且 對當前用戶可讀
-w 存在且 對當前用戶可寫
-x 存在且 對對當前用戶可執行
-特殊權限測試:
-u 存在且有 suid
-g 存在且有 sgid
-k 存在且有 stick
-文件是否非空:
* -s 不空為真,空為假
-時間戳:
-N 文件自最近被讀后是否被修改過
-從屬關系測試:
-O 當前用戶是否 為文件屬主
-G 當前用戶是否 屬于文件屬組
-雙目測試:mtime 判斷修改時間
FILE1 -ef FILE2 是否互為硬鏈接
* FILE1 -nt FILE2 F1是否新于F2
FILE1 -ot FILE2 F1是否舊于F2
-a = 且
-o = 或
]#a=6 ]#[ $a -gt 0 -a $a -lt 9 ] && echo 0 ]#0
六、腳本的狀態返回值:
默認腳本執行的最后一條命令的狀態返回值;
自定義狀態退出狀態碼;
exit [n]: n 對應 $? 的值
shell進程遇到exit 即結束 n=[0-255]
利用命令狀態返回值判斷:
0:成功
1-255:失敗
#read [OPTION] 獲取用戶輸入信息,從而完成變量賦值
-p ""設置提示信息
-t # 設置超時時間
]#read -p "please enter a number:" num ]#please enter a number:5 ]#echo $num ]#5
====作業
一、腳本
1、編寫腳本/root/bin/systeminfo.sh,顯示當前主機系統信息,包括主機名,IPv4地址,操作系統版本,內核版本,CPU型號,內存大小,硬盤大小。
#!/bin/bash printf %-10s "hostname:" echo "`hostname`" printf %-10s "ip:" echo "`ifconfig|sed -nr 's/.*r:(.*) B.*/\1/p'`" printf %-10s "kernel:" echo "`uname -r|tr ':' ':\t'`" printf %-10s "OS:" echo "OS:\t\t`cat /etc/redhat-release`" printf %-10s "CPU:" echo "`lscpu|grep "Model name"|tr -d " "|cut -d: -f2`" printf %-10s "Mem:" echo "free|sed -n 2p|tr -s ' '|cut -d' ' -f2" printf %-10s "DiskSize:" echo "`lsblk|sed -n 2p|tr -s " "|cut -d " " -f4`"
2、編寫腳本/root/bin/backup.sh,可實現每日將/etc/目錄備份到/root/etcYYYY-mm-dd中
#!/bin/bash cp -a /etc /testdir/etc$(date +%F)&>/dev/null&&echo cp success||echo cp failuer
3、編寫腳本/root/bin/disk.sh,顯示當前硬盤分區中空間利用率最大的值
#!/bin/bash echo "the max usage:`df|grep '/dev/sd.*'|tr -s ' '|cut -d' ' -f5|sort|tail -1`"
4、編寫腳本/root/bin/links.sh,顯示正連接本主機的每個遠程主機的IPv4地址和連接數,并按連接數從大到小排序
#!/bin/bash netstat -t|tr -s ' ' ':'|cut -d: -f6|grep [0-9]|sort|uniq -c|sort -nr
5、寫一個腳本/root/bin/sumid.sh,計算/etc/passwd文件中的第10個用戶和第20用戶的ID之和
!/bin/bash ID1=`sed -n ${1}p /etc/passwd|cut -d: -f3` ID2=`sed -n ${2}p /etc/passwd|cut -d: -f3` let sum=ID1+ID2 echo "sum:$sum"
6、寫一個腳本/root/bin/sumspace.sh,傳遞兩個文件路徑作為參數給腳本,計算這兩個文件中所有空白行之和
#!/bin/bash blank1=`grep "^$" $1|wc -l` blank2=`grep "^$" $2|wc -l` let sum=blank1+blank2 echo "sum=$sum"
7、寫一個腳本/root/bin/sumfile.sh,統計/etc, /var, /usr目錄中共有多少個一級子目錄和文件
#!/bin/bash s1=`ls /etc|wc -l` s2=`ls /var|wc -l` s3=`ls /usr|wc -l` sum=$[s1+s2+s3] echo "sum=$sum"
8、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數;如果參數個數小于1,則提示用戶“至少應該給一個參數”,并立即退出;如果參數個數不小于1,則顯示第一個參數所指向的文件中的空白行數
#!/bin/bash echo -n "please enter a path:" read path [ ! -e $path ] && echo "file does not exist" && exit 5 || grep -c "^[[:space:]]*$" $path #[[ $# -lt 1 ]] && echo "at least one arg" && exit 5 || grep -c "^[[:space:]]*$" $1
9、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”
#!/bin/bash read -p "please ernter a ip adddress:" addr ping $addr -W1 -c1&>/dev/null && echo "IP address rechable!" || echo "IPaddress unrechable!"
10、判斷硬盤的每個分區空間和inode的利用率是否大于80,如果是,發郵件通知root磁盤滿
#!/bin/bash disk=`df |grep "/dev/sd.*"|cut -c 44-46|sort -nr|head -1` inode=`df -i|grep "/dev/sd.*"|cut -c 40-42|sort -nr|head -1` [ $disk -gt 80 -o $inode -gt 80 ]&&echo 'disk fulling'|mail root||echo dont worry
11、指定文件做為參數,判斷文件是否為.sh后綴,如果是,添加x權限
#!/bin/bash [ ! -e $1 ]&&echo "file dose not exist!"&&exit 23 [[ $1 =~ .*\.sh$ ]]&&chmod +x $1&&echo '+x done'||echo not sh
12、判斷輸入的IP是否為合法IP
#!/bin/bash echo -n "please enter a ip:" read ip echo $ip|egrep -q "^(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>\.){3}(\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>)$" && echo legal ip || echo illegal ip
13、計算1+2+3+…+100
#!/bin/bash seq -s '+' 1 100|bc
14、輸入起始值A和最后值B,計算從A+(A+1)…+(B-1)+B的總和
#!/bin/bash seq -s '+' $1 $2|bc
原創文章,作者:Jasper,如若轉載,請注明出處:http://www.www58058.com/34844