1、case語句
1.語法結構
2.應用案例
1)腳本傳不一樣值作不一樣事
2)根據用戶需求選擇作事
2、函數
1.什麼是函數?
2.如何定義函數?
3.函數如何調用?
1)當前命令行調用
2)定義到用戶的環境變量中
3)腳本中調用
3、綜合案例
1.任務背景
2.具體要求
3.綜合分析
4.落地實現
4、正則表達式
1.正則表達式是什麼?
2.正則能幹什麼?
3.正則當中名詞解釋
4.第一類正則表達式
1)正則中普一般用的元字符
2)正則中其餘經常使用元字符
3)擴展類正則經常使用元字符
5.第二類正則
6.正則表達式總結
5、正則元字符一欄表
6、正則練習做業
1.文件準備
2.具體要求
7、課後做業
腳本搭建web服務html1、case語句
- case語句爲多重匹配語句
- 若是匹配成功,執行相匹配的命令
說明:pattern表示須要匹配的模式 case var in 定義變量;var表明是變量名 pattern 1) 模式1;用 | 分割多個模式,至關於or command1 須要執行的語句 ;; 兩個分號表明命令結束 pattern 2) command2 ;; pattern 3) command3 ;; *) default,不知足以上模式,默認執行*)下面的語句 command4 ;; esac esac表示case語句結束
具體需求:當給程序傳入start、stop、restart三個不一樣參數時分別執行相應命令mysql
#!/bin/env bash case $1 in start|S) service apache start &>/dev/null && echo "apache 啓動成功" ;; stop|T) service apache stop &>/dev/null && echo "apache 中止成功" ;; restart|R) service apache restart &>/dev/null && echo "apache 重啓完畢" ;; *) echo "請輸入要作的事情..." ;; esac
具體需求:git
腳本提示讓用戶輸入須要管理的服務名,而後提示用戶須要對服務作什麼操做,如啓動,關閉等操做web
#!/bin/env bash read -p "請輸入你要管理的服務名稱(vsftpd):" service case $service in vsftpd|ftp) read -p "請選擇你須要作的事情(restart|stop):" action case $action in stop|S) service vsftpd stop &>/dev/null && echo "該$serivce服務已經中止成功" ;; start) service vsftpd start &>/dev/null && echo "該$serivce服務已經成功啓動" ;; esac ;; httpd|apache) echo "apache hello world" ;; *) echo "請輸入你要管理的服務名稱(vsftpd)" ;; esac
###㈢ 菜單提示讓用戶選擇須要作的事正則表達式
具體需求:sql
模擬一個多任務維護界面;當執行程序時先顯示總菜單,而後進行選擇後作相應維護監控操做shell
**********請選擇********* h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 *************************
思路:apache
落地實現:vim
#!/bin/env bash cat <<-EOF h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 EOF
#!/bin/bash #打印菜單 cat <<-EOF h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 EOF #讓用戶輸入須要的操做 while true do read -p "請輸入須要操做的選項[f|d]:" var1 case $var1 in h) cat <<-EOF h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 EOF ;; f) fdisk -l ;; d) df -h ;; m) free -m ;; u) uptime ;; q) exit ;; esac done #!/bin/bash #打印菜單 menu(){ cat <<-END h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 END } menu while true do read -p "請輸入你的操做[h for help]:" var1 case $var1 in h) menu ;; f) read -p "請輸入你要查看的設備名字[/dev/sdb]:" var2 case $var2 in /dev/sda) fdisk -l /dev/sda ;; /dev/sdb) fdisk -l /dev/sdb ;; esac ;; d) lsblk ;; m) free -m ;; u) uptime ;; q) exit ;; esac done
課堂練習:安全
方法1:
函數名() { 函數體(一堆命令的集合,來實現某個功能) }
方法2:
function 函數名() { 函數體(一堆命令的集合,來實現某個功能) echo hello echo world }
函數中==return==說明:
[root@MissHou shell04]# cat fun1.sh #!/bin/bash hello(){ echo "hello lilei $1" hostname } menu(){ cat <<-EOF 1. mysql 2. web 3. app 4. exit EOF } [root@MissHou shell04]# source fun1.sh [root@MissHou shell04]# . fun1.sh [root@MissHou shell04]# hello 888 hello lilei 888 MissHou.itcast.cc [root@MissHou shell04]# menu 1. mysql 2. web 3. app 4. exit
[root@MissHou shell05]# vim ~/.bashrc 文件中增長以下內容: hello(){ echo "hello lilei $1" hostname } menu(){ cat <<-EOF 1. mysql 2. web 3. app 4. exit EOF } 注意: 當用戶打開bash的時候會讀取該文件
#!/bin/bash #打印菜單 source ./fun1.sh menu(){ cat <<-END h 顯示命令幫助 f 顯示磁盤分區 d 顯示磁盤掛載 m 查看內存使用 u 查看系統負載 q 退出程序 END } menu //調用函數
##4. 應用案例
具體需求:
思路:
若是不輸一直提示輸入
代碼實現:
#!/bin/bash #該函數實現用戶若是不輸入內容則一直循環直到用戶輸入爲止,而且將用戶輸入的內容打印出來 input_fun() { input_var="" output_var=$1 while [ -z $input_var ] do read -p "$output_var" input_var done echo $input_var } input_fun 請輸入你的姓名: 或者 #!/bin/bash fun() { read -p "$1" var if [ -z $var ];then fun $1 else echo $var fi } #調用函數而且獲取用戶的姓名、性別、年齡分別賦值給name、sex、age變量 name=$(input_fun 請輸入你的姓名:) sex=$(input_fun 請輸入你的性別:) age=$(input_fun 請輸入你的年齡:) #根據用戶輸入的性別進行匹配判斷 case $sex in man) if [ $age -gt 18 -a $age -le 35 ];then echo "中年大叔你油膩了嗎?加油" elif [ $age -gt 35 ];then echo "保溫杯裏泡枸杞" else echo "年輕有爲。。。" fi ;; woman) xxx ;; *) xxx ;; esac
擴展延伸:
描述如下代碼含義: :() { :|:& } :
現有的跳板機雖然實現了統一入口來訪問生產服務器,yunwei用戶權限太大能夠操做跳板機上的全部目錄文件,存在數據被誤刪的安全隱患,因此但願你作一些安全策略來保證跳板機的正常使用。
歡迎使用Jumper-server,請選擇你要操做的主機: 1. DB1-Master 2. DB2-Slave 3. Web1 4. Web2 h. help q. exit
#!/bin/bash # jumper-server # 定義菜單打印功能的函數 menu() { cat <<-EOF 歡迎使用Jumper-server,請選擇你要操做的主機: 1. DB1-Master 2. DB2-Slave 3. Web1 4. Web2 h. help q. exit EOF } # 屏蔽如下信號 trap '' 1 2 3 19 # 調用函數來打印菜單 menu #循環等待用戶選擇 while true do # 菜單選擇,case...esac語句 read -p "請選擇你要訪問的主機:" host case $host in 1) ssh root@10.1.1.1 ;; 2) ssh root@10.1.1.2 ;; 3) ssh root@10.1.1.3 ;; h) clear;menu ;; q) exit ;; esac done 將腳本放到yunwei用戶家目錄裏的.bashrc裏執行: bash ~/jumper-server.sh exit
進一步完善需求
爲了進一步加強跳板機的安全性,工做人員經過跳板機訪問生產環境,可是不能在跳板機上停留。
#!/bin/bash #公鑰推送成功 trap '' 1 2 3 19 #打印菜單用戶選擇 menu(){ cat <<-EOF 歡迎使用Jumper-server,請選擇你要操做的主機: 1. DB1-Master 2. DB2-Slave 3. Web1 4. Web2 h. help q. exit EOF } #調用函數來打印菜單 menu while true do read -p "請輸入你要選擇的主機[h for help]:" host #經過case語句來匹配用戶所輸入的主機 case $host in 1|DB1) ssh root@10.1.1.1 ;; 2|DB2) ssh root@10.1.1.2 ;; 3|web1) ssh root@10.1.1.250 ;; h|help) clear;menu ;; q|quit) exit ;; esac done 本身完善功能: 1. 用戶選擇主機後,須要事先推送公鑰;如何判斷公鑰是否已推 2. 好比選擇web1時,再次提示須要作的操做,好比: clean log 重啓服務 kill某個進程
回顧信號:
1) SIGHUP 從新加載配置 2) SIGINT 鍵盤中斷^C 3) SIGQUIT 鍵盤退出 9) SIGKILL 強制終止 15) SIGTERM 終止(正常結束),缺省信號 18) SIGCONT 繼續 19) SIGSTOP 中止 20) SIGTSTP 暫停^Z
正則表達式(Regular Expression、regex或regexp,縮寫爲RE),也譯爲正規表示法、常規表示法,是一種字符模式,用於在查找過程當中==匹配指定的字符==。
許多程序設計語言都支持利用正則表達式進行字符串操做。例如,在Perl中就內建了一個功能強大的正則表達式引擎。
正則表達式這個概念最初是由Unix中的工具軟件(例如sed和grep)普及開的。
支持正則表達式的程序如:locate |find| vim| grep| sed |awk
元字符
指那些在正則表達式中具備特殊意義的==專用字符==,如:點(.) 星(*) 問號(?)等
前導字符
位於元字符前面的字符. ab**==c==* aoo==o==.**
元字符 | 功能 | 備註 |
---|---|---|
. | 匹配除了換行符之外的==任意單個==字符 | |
* | ==前導字符==出現==0==次或==連續屢次== | |
.* | 任意長度字符 | ab.* |
^ | 行首(以...開頭) | ^root |
$ | 行尾(以...結尾) | bash$ |
^$ | 空行 | |
[] | 匹配括號裏任意單個字符或一組單個字符 | [abc] |
[^] | 匹配不包含括號裏任一單個字符或一組單個字符 | [^abc] |
^[] | 匹配以括號裏任意單個字符或一組單個字符開頭 | ^[abc] |
\^[\^] | 匹配不以括號裏任意單個字符或一組單個字符開頭 | \^[^abc] |
# cat 1.txt ggle gogle google gooogle goooooogle gooooooogle taobao.com taotaobaobao.com jingdong.com dingdingdongdong.com 10.1.1.1 Adfjd8789JHfdsdf/ a87fdjfkdLKJK 7kdjfd989KJK; bSKJjkksdjf878. cidufKJHJ6576, hello world helloworld yourself
元字符 | 功能 | 備註 |
---|---|---|
\< | 取單詞的頭 | |
\> | 取單詞的尾 | |
\< \> | 精確匹配 | |
\{n\} | 匹配前導字符==連續出現n次== | |
\{n,\} | 匹配前導字符==至少出現n次== | |
\{n,m\} | 匹配前導字符出現==n次與m次之間== | |
\( \) | 保存被匹配的字符 | |
\d | 匹配數字(grep -P) | [0-9] |
\w | 匹配字母數字下劃線(grep -P) | [a-zA-Z0-9_] |
\s | 匹配空格、製表符、換頁符(grep -P) | [\t\r\n] |
舉例說明:
需求:將10.1.1.1替換成10.1.1.254 1)vim編輯器支持正則表達式 # vim 1.txt :%s#\(10.1.1\).1#\1.254#g :%s/\(10.1.1\).1/\1.254/g 2)sed支持正則表達式【後面學】 # sed -n 's#\(10.1.1\).1#\1.254#p' 1.txt 10.1.1.254 說明: 找出含有10.1.1的行,同時保留10.1.1並標記爲標籤1,以後可使用\1來引用它。 最多能夠定義9個標籤,從左邊開始編號,最左邊的是第一個。 需求:將helloworld yourself 換成hellolilei myself # vim 1.txt :%s#\(hello\)world your\(self\)#\1lilei my\2#g # sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt hellolilei myself # sed -n 's/helloworld yourself/hellolilei myself/p' 1.txt hellolilei myself # sed -n 's/\(hello\)world your\(self\)/\1lilei my\2/p' 1.txt hellolilei myself Perl內置正則: \d 匹配數字 [0-9] \w 匹配字母數字下劃線[a-zA-Z0-9_] \s 匹配空格、製表符、換頁符[\t\r\n] # grep -P '\d' 1.txt # grep -P '\w' 2.txt # grep -P '\s' 3.txt
==醜話說在前面:==
我說我比較特殊,你要相信!不然我錯給你看:smirk:
grep你要用我,必須加 ==-E== 或者 讓你兄弟egrep
來找我
擴展元字符 | 功能 | 備註 |
---|---|---|
+ | 匹配一個或多個前導字符 | bo+ 匹配boo、 bo |
? | 匹配零個或一個前導字符 | bo? 匹配b、 bo |
| | 或 | 匹配a或b |
() | 組字符(當作總體) | (my|your)self:表示匹配myself或匹配yourself |
{n} | 前導字符重複n次 | |
{n,} | 前導字符重複至少n次 | |
{n,m} | 前導字符重複n到m次 |
舉例說明:
# grep "root|ftp|adm" /etc/passwd # egrep "root|ftp|adm" /etc/passwd # grep -E "root|ftp|adm" /etc/passwd # grep -E 'o+gle' test.txt # grep -E 'o?gle' test.txt # egrep 'go{2,}' 1.txt # egrep '(my|your)self' 1.txt 使用正則過濾出文件中的IP地址: # grep '[0-9]\{2\}\.[0-9]\{1\}\.[0-9]\{1\}\.[0-9]\{1\}' 1.txt 10.1.1.1 # grep '[0-9]{2}\.[0-9]{1}\.[0-9]{1}\.[0-9]{1}' 1.txt # grep -E '[0-9]{2}\.[0-9]{1}\.[0-9]{1}\.[0-9]{1}' 1.txt 10.1.1.1 # grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' 1.txt 10.1.1.1 # grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt 10.1.1.1
表達式 | 功能 | 示例 |
---|---|---|
[:alnum:] | 字母與數字字符 | [[:alnum:]]+ |
[:alpha:] | 字母字符(包括大小寫字母) | [[:alpha:]]{4} |
[:blank:] | 空格與製表符 | [[:blank:]]* |
[:digit:] | 數字 | [[:digit:]]? |
[:lower:] | 小寫字母 | [[:lower:]]{4,} |
[:upper:] | 大寫字母 | [[:upper:]]+ |
[:punct:] | 標點符號 | [[:punct:]] |
[:space:] | 包括換行符,回車等在內的全部空白 | [[:space:]]+ |
[root@server shell05]# grep -E '^[[:digit:]]+' 1.txt [root@server shell05]# grep -E '^[^[:digit:]]+' 1.txt [root@server shell05]# grep -E '[[:lower:]]{4,}' 1.txt
把握一個原則,讓你輕鬆搞定可惡的正則符號:
元字符:在正則中,具備特殊意義的專用字符,如: 星號(*)、加號(+)等
前導字符:元字符前面的字符叫前導字符
元字符 | 功能 | 示例 |
---|---|---|
* | 前導字符出現0次或者連續屢次 | ab* abbbb |
. | 除了換行符之外,任意單個字符 | ab. ab8 abu |
.* | 任意長度的字符 | ab.* adfdfdf |
[] | 括號裏的任意單個字符或一組單個字符 | [abc][0-9][a-z] |
[^] | 不匹配括號裏的任意單個字符或一組單個字符 | [^abc] |
^[] | 匹配以括號裏的任意單個字符開頭 | ^[abc] |
\^[^] | 不匹配以括號裏的任意單個字符開頭 | |
^ | 行的開頭 | ^root |
$ | 行的結尾 | bash$ |
^$ | 空行 | |
\{n\}和{n} | 前導字符連續出現n次 | [0-9]\{3\} |
\{n,\}和{n,} | 前導字符至少出現n次 | [a-z]{4,} |
\{n,m\}和{n,m} | 前導字符連續出現n-m次 | go{2,4} |
\<\> | 精確匹配單詞 | \<hello\> |
\(\) | 保留匹配到的字符 | \(hello\) |
+ | 前導字符出現1次或者屢次 | [0-9]+ |
? | 前導字符出現0次或者1次 | go? |
| | 或 | \^root|\^ftp |
() | 組字符 | (hello|world)123 |
\d | perl內置正則 | grep -P \d+ |
\w | 匹配字母數字下劃線 |
# vim test.txt Aieur45869Root0000 9h847RkjfkIIIhello rootHllow88000dfjj 8ikuioerhfhupliooking hello world 192.168.0.254 welcome to uplooking. abcderfkdjfkdtest rlllA899kdfkdfj iiiA848890ldkfjdkfj abc 12345678908374 123456@qq.com 123456@163.com abcdefg@itcast.com23ed
一、查找不以大寫字母開頭的行(三種寫法)。 grep '^[^A-Z]' 2.txt grep -v '^[A-Z]' 2.txt grep '^[^[:upper:]]' 2.txt 二、查找有數字的行(兩種寫法) grep '[0-9]' 2.txt grep -P '\d' 2.txt 三、查找一個數字和一個字母連起來的 grep -E '[0-9][a-zA-Z]|[a-zA-Z][0-9]' 2.txt 四、查找不以r開頭的行 grep -v '^r' 2.txt grep '^[^r]' 2.txt 五、查找以數字開頭的 grep '^[0-9]' 2.txt 六、查找以大寫字母開頭的 grep '^[A-Z]' 2.txt 七、查找以小寫字母開頭的 grep '^[a-z]' 2.txt 八、查找以點結束的 grep '\.$' 2.txt 九、去掉空行 grep -v '^$' 2.txt 十、查找徹底匹配abc的行 grep '\<abc\>' 2.txt 十一、查找A後有三個數字的行 grep -E 'A[0-9]{3}' 2.txt grep 'A[0-9]\{3\}' 2.txt 十二、統計root在/etc/passwd裏出現了幾回 grep -o 'root' 1.txt |wc -l 1三、用正則表達式找出本身的IP地址、廣播地址、子網掩碼 ifconfig eth0|grep Bcast|grep -o '[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}' ifconfig eth0|grep Bcast| grep -E -o '([0-9]{1,3}.){3}[0-9]{1,3}' ifconfig eth0|grep Bcast| grep -P -o '\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}' ifconfig eth0|grep Bcast| grep -P -o '(\d{1,3}.){3}\d{1,3}' ifconfig eth0|grep Bcast| grep -P -o '(\d+.){3}\d+' # egrep --color '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0 IPADDR=10.1.1.1 NETMASK=255.255.255.0 GATEWAY=10.1.1.254 # egrep --color '[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}' /etc/sysconfig/network-scripts/ifcfg-eth0 IPADDR=10.1.1.1 NETMASK=255.255.255.0 GATEWAY=10.1.1.254 1四、找出文件中的ip地址而且打印替換成172.16.2.254 grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt |sed -n 's/192.168.0.\(254\)/172.16.2.\1/p' 1五、找出文件中的ip地址 grep -o -E '([0-9]{1,3}\.){3}[0-9]{1,3}' 1.txt 1六、找出所有是數字的行 grep -E '^[0-9]+$' test 1七、找出郵箱地址 grep -E '^[0-9]+@[a-z0-9]+\.[a-z]+$' grep --help: 匹配模式選擇: Regexp selection and interpretation: -E, --extended-regexp 擴展正則 -G, --basic-regexp 基本正則 -P, --perl-regexp 調用perl的正則 -e, --regexp=PATTERN use PATTERN for matching -f, --file=FILE obtain PATTERN from FILE -i, --ignore-case 忽略大小寫 -w, --word-regexp 匹配整個單詞
要求以下:
參考腳本:
參考: #!/bin/bash conf=/etc/httpd/conf/httpd.conf input_fun() { input_var="" output_var=$1 while [ -z $input_var ] do read -p "$output_var" input_var done echo $input_var } ipaddr=$(input_fun "Input Host ip[192.168.0.1]:") web_host_name=$(input_fun "Input VirtualHostName [www.test.cc]:") root_dir=$(input_fun "Input host Documentroot dir:[/var/www/html]:") [ ! -d $root_dir ] && mkdir -p $root_dir chown apache.apache $root_dir && chmod 755 $root_dir echo this is $web_host_name > $root_dir/index.html echo "$ipaddr $web_host_name" >> /etc/hosts [ -f $conf ] && cat >> $conf <<end NameVirtualHost $ipaddr:80 <VirtualHost $ipaddr:80> ServerAdmin webmaster@$web_host_name DocumentRoot $root_dir ServerName $web_host_name ErrorLog logs/$web_host_name-error_log CustomLog logs/$web_host_name-access_loh common </VirtualHost> end
——————————本文到此結束,感謝閱讀——————————————