函式基本概述
1. 函式基本概述
01. 什麼是函式?
函式其實就是一堆命令的合集,用來完成特定功能的程式碼塊,你可以對它進行自定義命令,並且可以在指令碼中任意位置使用這個函式,要使用定義的函式,只需要填寫函式名稱就可以了。
02. 函式的作用
1.使用函式可以讓程式碼模組化,便於程式碼的複用,同時增加指令碼的可讀性。
2.函式和變數類似,必須先定義才可使用,如果定義不呼叫則不會被執行。
2. 函式基本使用
01. 如何定義Shell函式,可以通過如下兩種方式進行定義。
方式一
函式名() {
command1
command2
...
commandN
}
方式二
function 函式名 {
command1
command2
...
commandN
}
如何呼叫Shell函式,直接使用函式名呼叫即可。在函式內部也可以使用$1、$2..$n的方式傳遞引數。**
#1.命令列定義函式
[root@qiudao /scripts]# fun1() { echo "hello world"; }
#2.命令列呼叫函式
[root@qiudao /scripts]# fun1
hello world
#給函式傳遞引數
[root@qiudao /scripts]# fun2() { echo "hello $1"; }
[root@qiudao /scripts]# fun2 linux
hello linux
#4.給函式傳遞多個引數{$*,接收所有的引數傳遞}
[root@qiudao /scripts]# fun3() { echo "hello $*"; }
[root@qiudao /scripts]# fun3 zhangsan
3. 函式引數傳遞
如何向函式傳遞引數,其實函式傳參和指令碼傳參類似,都是使用$1..$9..方式。
01. 函式傳參示例,使用變數方式傳遞固定值
[root@qiudao /scripts]# cat fun-1.sh
#!/bin/bash
fun_1() {
echo "$num"
}
num=10 #傳遞引數
fun_1 #呼叫函式
#執行指令碼
[root@qiudao /scripts]# sh fun-1.sh
10
02. 函式傳參示例,使用變數方式傳遞可變的值
[root@qiudao /scripts]# cat fun-2.sh
\#!/bin/bash
fun_1() {
echo "$num"
}
num=$1 #將指令碼的第一個位置引數傳遞給變數num
fun_1 #呼叫函式
\#執行指令碼
[root@qiudao /scripts]# sh fun-2.sh 20
20
03. 函式傳參示例,傳遞多個位置引數
[root@qiudao /scripts]# cat fun-3.sh
#!/bin/bash
fun_1() {
echo "$1" #接收執行函式是傳遞的第一個引數
}
fun_1 $1 #接收指令碼第一個位置引數,傳入函式中算第一個引數
fun_1 $2 #接收指令碼第二個位置引數,傳入函式中算第一個引數
fun_1 $3 #接收指令碼第三個位置引數,傳入函式中算第一個引數
#執行指令碼
[root@qiudao /scripts]# sh fun-3.sh 10 20 30
10
20
30
[root@qiudao /scripts]# cat fun-3.sh
#!/bin/bash
fun_1() {
echo "$1"
}
fun_1 $1 $2 $3
fun_1 $2
fun_1 $3
[root@qiudao shell]# sh fun.sh 1 2 3
1
2
3
04. 函式傳參示例,傳遞多個函式引數
[root@qiudao /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@qiudao /scripts]# sh fun-4.sh 10 20 30
傳遞引數的值為,10 20 30
05. 函式傳參示例,將指令碼的位置引數與函式的位置引數發生聯動。
[root@qiudao /scripts]# cat fun-5.sh
#!/bin/bash
fun_1() {
echo "$num1" "$num2" "$num3"
}
num1=$1 #將指令碼位置引數一的值傳遞給變數num1
num2=$2 #將指令碼位置引數二的值傳遞變數給num2
num3=$3 #將指令碼位置引數二的值傳遞變數給num3
rc=$(fun_1) #將函式執行的結果儲存至rc變數中,便於後續echo輸出
echo "傳遞引數的值為,$rc"
#執行指令碼
[root@qiudao /scripts]# sh fun-5.sh 10 20 30
傳遞引數的值為,10 20 30
06. 函式傳參使用場景示例,寫一個指令碼,該指令碼可以實現計算器的功能,可以進行加減乘除四種計算
[root@qiudao /opt]# cat fun-6.sh
#!/usr/bin/bash
cale (){
case $2 in
+)
echo $1 + $3 = $(( $1 + $3 ))
;;
-)
echo $1 - $3 = $(( $1 - $3 ))
;;
/)
echo $1 / $3 = $(( $1 / $3 ))
;;
x)
echo "$1 x $3 = $(( $1 * $ ))"
esac
}
cale $1 $2 $3
07. 函式傳參使用場景示例,需求描述:寫一個指令碼,實現nginx服務的啟動、停止、重啟。
[root@backup scripts]# cat stat.sh
#!/bin/bash
source /etc/init.d/functions
if [ $# -ne 1 ];then
echo "Usage:$0 {start|stop|reload|status|restart}"
exit
fi
nc=$1
rc() {
if [ $? -eq 0 ];then
action "nginx is $nc 成功" /bin/true
else
action "nginx is $nc 失敗" /bin/false
fi
}
start() {
if [ ! -f /var/run/nginx.pid ];then
/usr/sbin/nginx
rc
else
echo "nginx正在執行"
fi
}
stop() {
if [ -f /var/run/nginx.pid ];then
/usr/sbin/nginx -s stop
rc
else
echo "nginx不在執行"
fi
}
reload () {
if [ -f /var/run/nginx.pid ];then
/usr/sbin/nginx -s reload
rc
else
echo "nginx不在執行,無法重啟"
fi
}
status () {
if [ -f /var/run/nginx.pid ];then
echo "nginx正在執行"
else
echo "nginx不在執行,無法重啟"
fi
}
case $nc in
start)
start
;;
stop)
stop
;;
reload)
reload
;;
restart)
nc=stop
stop
sleep 2
nc=start
start
;;
status)
status
;;
*)
echo "Usage: $0 {start|stop|reload|status}"
exit
esac
4. 函式狀態返回
Shell的函式返回值,也算是退出的狀態。在Shell中只有echo、return兩種方式。
1.使用return返回值:只能返回0-255的整數,函式使用return返回值,通常只是用來供其他地方呼叫獲取狀態,因此通常僅返回0或1;0表示成功,1表示失敗。
2.使用echo返回值:使用echo可以返回任何字串結果,通常用於返回資料,比如一個字串值或者列表值。
01. Shell函式echo、return返回值示例
[root@qiudao /scripts]# cat fun_echo_return.sh
#!/bin/bash
fun_echo_return() {
echo 100 #返回函式執行後的資料
return 1 #返回函式執行後的狀態碼(放置最後)
}
result=`fun_echo_return`
echo "函式的狀態碼是:$? "
echo "函式的返回值是:$result "
#執行指令碼
[root@qiudao /scripts]# sh fun_echo_return.sh
函式的狀態碼是:1
函式的返回值是:100
02. Shell函式return返回值使用場景示例
#return示例一:
[root@qiudao /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@qiudao /scripts]# sh fun_return.sh
該檔案存在 /etc/passwd
#return示例二:(瞭解即可)
[root@qiudao /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@qiudao /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@qiudao /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
}
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
##########################################
## 1、作業系統發行版本
## 2、部署yum源
## 3、安裝系統軟體包
## 4、關閉Selinux
## 5、關閉Firewalld
## 6、配置SSHD服務
## 7、加大檔案描述符
## 8、同步系統時間
## 9、列印選單
## 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@qiudao /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