Shell05--函數應用

Shell05---函數應用

1. 函數基本概述

01. 什麼是函數?
函數其實就是一堆命令的合集,用來完成特定功能的代碼塊,你能夠對它進行自定義命令,而且能夠在腳本中任意位置使用這個函數,要使用定義的函數,只須要填寫函數名稱就能夠了。
02. 函數的做用nginx

1.使用函數可讓代碼模塊化,便於代碼的複用,同時增長腳本的可讀性。
2.函數和變量相似,必須先定義纔可以使用,若是定義不調用則不會被執行。shell

2. 函數基本使用

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

3. 函數參數傳遞

如何向函數傳遞參數,其實函數傳參和腳本傳參相似,都是使用$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

4. 函數狀態返回

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

5. 函數場景示例

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
相關文章
相關標籤/搜索