01. 什麼是函數?
函數其實就是一堆命令的合集,用來完成特定功能的代碼塊,你能夠對它進行自定義命令,而且能夠在腳本中任意位置使用這個函數,要使用定義的函數,只須要填寫函數名稱就能夠了。
02. 函數的做用nginx
1.使用函數可讓代碼模塊化,便於代碼的複用,同時增長腳本的可讀性。
2.函數和變量相似,必須先定義纔可以使用,若是定義不調用則不會被執行。shell
01. 如何定義Shell函數,能夠經過以下兩種方式進行定義。vim
#方式一函數名() { command1 command2 ... commandN } #方式二function 函數名 { command1 command2 ... commandN }
02. 如何調用Shell函數,直接使用函數名調用便可。在函數內部也可使用$一、\(2..\)n的方式傳遞參數。bash
#1.命令行定義函數 [root@gjy /scripts]# fun1() { echo "hello world"; } #2.命令行調用函數 [root@gjy /scripts]# fun1 hello world #3.給函數傳遞參數 [root@gjy /scripts]# fun2() { echo "hello $1"; } [root@gjy /scripts]# fun2 linux hello linux #4.給函數傳遞多個參數{$*,接收全部的參數傳遞} [root@gjy /scripts]# fun3() { echo "hello $*"; } [root@gjy /scripts]# fun3 zhangsan lisi wangwu hello zhangsan lisi wangwu
如何向函數傳遞參數,其實函數傳參和腳本傳參相似,都是使用$1..$9..方式。ssh
01. 函數傳參示例,使用變量方式傳遞固定值curl
[root@gjy /scripts]# cat fun-1.sh #!/bin/bash fun_1() { echo "$num" } num=10 #傳遞參數 fun_1 #調用函數#執行腳本 [root@gjy /scripts]# sh fun-1.sh 10
02. 函數傳參示例,使用變量方式傳遞可變的值模塊化
[root@gjy /scripts]# cat fun-2.sh #!/bin/bash fun_1() { echo "$num" } num=$1 #將腳本的第一個位置參數傳遞給變量num fun_1 #調用函數#執行腳本 [root@gjy /scripts]# sh fun-2.sh 20 20
03. 函數傳參示例,傳遞多個位置參數函數
[root@gjy /scripts]# cat fun-3.sh #!/bin/bash fun_1() { echo "$1" #接收執行函數是傳遞的第一個參數 } fun_1 $1 #接收腳本第一個位置參數,傳入函數中算第一個參數 fun_1 $2 #接收腳本第二個位置參數,傳入函數中算第一個參數 fun_1 $3 #接收腳本第三個位置參數,傳入函數中算第一個參數#執行腳本 [root@gjy /scripts]# sh fun-3.sh 10 20 30 10 20 30 [root@gjy /scripts]# cat fun-3.sh #!/bin/bash fun_1() { echo "$1" } fun_1 $1 $2 $3 fun_1 $2 fun_1 $3 [root@gjy shell]# sh fun.sh 1 2 3 1 2 3
04. 函數傳參示例,傳遞多個函數參數工具
[root@gjy /scripts]# cat fun-4.sh #!/bin/bash fun_1() { echo "$1" "$2" "$3" #函數接收傳遞三個參數 } #rc=$(fun_1 10 20 30) #傳遞固定的值 rc=$(fun_1 $1 $2 $3) #傳遞可變的值 echo "傳遞參數的值爲,$rc"#執行腳本 [root@gjy /scripts]# sh fun-4.sh 10 20 30 傳遞參數的值爲,10 20 30
05. 函數傳參示例,將腳本的位置參數與函數的位置參數發生聯動。
[root@gjy /scripts]# cat fun-5.sh #!/bin/bash fun_1() { echo "$num1" "$num2" "$num3" } num1=$1 #將腳本位置參數一的值傳遞給變量num1 num2=$2 #將腳本位置參數二的值傳遞變量給num2 num3=$3 #將腳本位置參數二的值傳遞變量給num3rc=$(fun_1) #將函數執行的結果保存至rc變量中,便於後續echo輸出echo "傳遞參數的值爲,$rc"#執行腳本 [root@gjy /scripts]# sh fun-5.sh 10 20 30 傳遞參數的值爲,10 20 30
06. 函數傳參使用場景示例,寫一個腳本,該腳本能夠實現計算器的功能,能夠進行加減乘除四種計算
[root@gjy /opt]# cat fun-6.sh #!/usr/bin/bashcale (){ case $2 in +) echo $1 + $3 = $(( $1 + $3 )) ;; -) echo $1 - $3 = $(( $1 - $3 )) ;; /) echo $1 / $3 = $(( $1 / $3 )) ;; x) echo "$1 x $3 = $(( $1 * $3 ))" esac } cale $1 $2 $3
07. 函數傳參使用場景示例,需求描述:寫一個腳本,實現nginx服務的啓動、中止、重啓。
[root@gjy /scripts]# cat fun_nginx.sh #!/usr/bin/bash # manager Nginx start stop restart reload source /etc/init.d/functions if [ $# -ne 1 ];then echo "Usage: $0 {start|stop|reload|restart|status}" exit fi act=$1 te(){ if [ $? -eq 0 ];then action "Nginx Is $act" /bin/true else action "Nginx Is $act" /bin/false fi } start() { if [ ! -f /var/run/nginx.pid ];then /usr/sbin/nginx te else echo "nginx服務正在運行" fi } stop() { if [ -f /var/run/nginx.pid ];then /usr/sbin/nginx -s stop else echo "nginx服務再也不運行" fi } reload() { if [ -f /var/run/nginx.pid ];then /usr/sbin/nginx -s reload else echo "nginx服務不在運行,沒法進行重啓" fi } status(){ Ngx_status_pid=$(ps aux|grep "[n]ginx"|grep master|awk '{print $2}') Nginx_Status_Port=$(netstat -lntp|grep nginx|awk '{print $4}') echo "Nginx_status_Pid: $Ngx_status_pid" echo "Nginx_status_Port: $Nginx_Status_Port" } case $1 in start) start ;; stop) stop ;; restart) stop sleep 1 start ;; reload) reload ;; status) status ;; *) echo "Usage: $0 {start|stop|status|restart|reload|}" esac
Shell的函數返回值,也算是退出的狀態。在Shell中只有echo、return兩種方式。
1.使用return返回值:
只能返回0-255的整數,函數使用return返回值,一般只是用來供其餘地方調用獲取狀態,所以一般僅返回0或1;0表示成功,1表示失敗。
2.使用echo返回值:
使用echo能夠返回任何字符串結果,一般用於返回數據,好比一個字符串值或者列表值。
01. Shell函數echo、return返回值示例
[root@gjy /scripts]# cat fun_echo_return.sh #!/bin/bash fun_echo_return() { echo 100 #返回函數執行後的數據 return 1 #返回函數執行後的狀態碼(放置最後) } result=`fun_echo_return` echo "函數的狀態碼是:$? " echo "函數的返回值是:$result " #執行腳本 [root@gjy /scripts]# sh fun_echo_return.sh 函數的狀態碼是:1 函數的返回值是:100
02. Shell函數return返回值使用場景示例
#return示例一: [root@gjy /scripts]# cat fun_return.sh #!/bin/bash file=/etc/passwd #定義文件 t_file() { if [ -f $file ];then return 0 else return 1 fi } #調用函數,並根據函數返回狀態碼進行輸出 t_file && echo "該文件存在 $file" || echo "該文件不存在 $file"#執行腳本 [root@gjy /scripts]# sh fun_return.sh 該文件存在 /etc/passwd#return示例二:(瞭解便可) [root@gjy /scripts]# cat fun_nginx_run.sh #!/bin/bash this_pid=$$ is_nginx_running() { ps -ef|grep nginx |grep -v grep |grep -v $this_pid &>/dev/null if [ $? -eq 0 ];then return 0 else return 1 fi } #調用函數,並根據函數返回狀態碼進行輸出 is_nginx_running && echo "Nginx is running" || echo "Nginx is stoped"
03. Shell函數返回值場景練習,例:猜數字遊戲。
1.若是用戶輸入的數值大於0且小於10則返回0
2.若是用戶輸入的數值大於等於10且小於20則返回1
3.若是用戶輸入的數值大於等於20且小於30則返回2
4.輸入其他數值則返回3
[root@gjy /scripts]# cat fun_return-3.sh #!/bin/bash checknum() { read -p "請輸入對應的數字:" num if [ $num -ge 0 -a $num -le 10 ];then return 0 elif [ $num -gt 10 -a $num -le 20 ];then return 1 elif [ $num -gt 20 -a $num -le 30 ];then return 2 else return 3 fi } #調用函數,函數執行後會經過return返回對應的狀態碼 checknum rc=$? #根據函數返回值進行判斷 if [ $rc -eq 0 ];then echo "你輸入的數字是:$num,大於0小於10" elif [ $rc -eq 1 ];then echo "你輸入的數字是:$num,大於10小於20" elif [ $rc -eq 2 ];then echo "你輸入的數字是:$num,大於20小於30" else echo "你輸入的數字是:$num,超出範圍!請從新輸入" fi
01. 系統初始化版本
[root@gjy /scripts]# cat system.sh #!/bin/bash #1.顯示系統版本 check_system_version() { awk '{print $(NF-1)}' /etc/redhat-release } #2.更新yum源 check_yum() { tt=$(awk '{print $(NF-1)}' /etc/redhat-release) if [ ${tt%%.*} -eq "6" ];then mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/.*repo /etc/yum.repos.d/backup/ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo elif [ ${tt%%.*} -eq "7" ];then mkdir -p /etc/yum.repos.d/backup mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/ curl -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo curl -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo fi yum clean all && yum makecache } #3.安裝基礎軟件包 package_install() { yum install -y net-tools vim tree htop iftop \ iotop lrzsz wget unzip telnet nmap nc ntpdate \ bash-completion bash-completion-extra sysstat rsync nfs-utils -y } #4.關閉selinux disable_selinux() { sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config setenforc 0 &> /dev/null } #5.關閉firewalld disable_firewalld() { systemctl stop firewalld.service systemctl disable firewalld.service } #6.配置sshd服務 ssh_config() { sed -i 's/#UseDNS yes/UseDNS no/g' /etc/ssh/sshd_config sed -i 's/GSSAPIAuthentication yes/GSSAPIAuthentication no/g' /etc/ssh/sshd_config } #7.加大文件描述符 limit_conf() { echo '* - nofile 65535 ' >>/etc/security/limits.conf } #8.時間同步 date_time() { echo '*/5 * * * * /usr/sbin/ntpdate ntp1.aliyun.com &>/dev/null' >/var/spool/cron/root } menu() { cat <<EOF ########################################## ## 一、操做系統發行版本 ## ## 二、部署yum源 ## ## 三、安裝系統軟件包 ## ## 四、關閉Selinux ## ## 五、關閉Firewalld ## ## 六、配置SSHD服務 ## ## 七、加大文件描述符 ## ## 八、同步系統時間 ## ## 九、打印菜單 ## ## q、退出程序 ## ########################################## EOF } #打印菜單 menu while true do read -p "您想幹什麼?就請輸入上面對應的字符:" n case $n in 1) check_system_version ;; 2) check_yum &>/dev/null echo $? &>/dev/null && echo "yum源更新完成" || echo "yum源更新失敗" ;; 3) echo "安裝軟件包須要一部分時間,請耐心等待,正在安裝中......." package_install &>/dev/null echo $? &>/dev/null && echo "基礎軟件包安裝完成" || echo "基礎軟件包安裝報錯" ;; 4) disable_selinux &>/dev/null echo $? &>/dev/null && echo "Selinux 關閉成功" || echo "Selinux 關閉失敗" ;; 5) disable_firewalld &>/dev/null echo $? &>/dev/null && echo "Firewalld 關閉成功" || echo "Firewalld 關閉失敗" ;; 6) ssh_config &>/dev/null echo $? &>/dev/null && echo "sshd服務配置完成" || echo "sshd服務配置報錯" ;; 7) limit_conf &>/dev/null echo $? &>/dev/null && echo "文件描述符數量修改爲功" || echo "文件描述符數量修改失敗" ;; 8) date_time &>/dev/null echo $? &>/dev/null && echo "定時任務添加成功" || echo "定時任務添加失敗" ;; 9) clear menu ;; q) echo "您即將退出程序!" exit 1 esac done
02. 編寫虛擬機管理腳本
安裝虛擬機
關閉虛擬機
打開虛擬機
克隆虛擬機
退出程序
03. 編寫系統管理工具箱
查看內存的使用狀況
查看磁盤的使用狀況
查看系統的負載
等等
q鍵退出程序
[root@gjy /scripts]# cat case-6.sh #!/bin/bash menu() { cat <<-EOF ############################# ## h 命令幫助## ## d 磁盤使用狀況 ## m 內存使用狀況 ## v 系統版本 ## k 系統內核版本 ## n 系統靜態主機名 ## e eth0網卡ip地址 ## i 外網ip地址 ## u 系統負載狀況## q 退出程序 ############################# EOF } menu while true do read -p "根據上方的菜單,選擇你要查看的信息: " sys case $sys in h) clear menu ;; d) clear df -h ;; m) clear free -m ;; v) clear awk '{print $1,$2,$4}' /etc/redhat-release ;; k) clear uname -r ;; n) clear hostnamectl|grep "Static hostname"|awk '{print $3}' ;; e) clear ifconfig eth0|awk 'NR==2{print $2}' ;; i) clear curl -s icanhazip.com ;; q) clear exit ;; *) clear echo "USAGE: $0 [ h | d | m | v | k | n | e | i | q ]" esac done