Shell
高级编程 Day06 —— Shell函数的知识与实践
1 Shell函数的概念与作用介绍
- 函数的作用就是将程序里多次被调用的相同代码组合起来(函数体),并为其取一个名字(即函数名),其他所有想重复调用这部分代码的地方只需要调用这个名字就可以了。当需要修改这部分重复代码时,只需要改变函数体内的一份代码即可实现对所有调用的修改,也可以把函数独立地写到文件里,当需要调用函数时,再加载进来使用。
- Shell函数的优势整理
- 把相同的程序段定义成函数,可以减少整个程序的代码量,提升开发效率。
- 增加程序的可读性、易读性,提升管理效率。
- 可以实现程序功能模块化,使得程序具备通用性(可移植性)。
2 Shell函数的语法
# 其标准写法为;
function 函数名() {
指令...
return n
}
# 简化写法1:
function 函数名 {
指令...
return n
}
# 简化写法2:
函数名() {
指令...
return n
}
3 Shell函数的执行
- Shell的函数分为最基本的函数和可以传参的函数两种
- 1)执行不带参数的函数时,直接输入函数名即可
函数名
- 注意:
- 执行Shell函数时,函数名前的function和函数后的小括号都不要带。
- 函数的定义必须在要执行的程序前面定义或加载
- Shell执行系统中各种程序的执行顺序为:系统别名->函数->系统命令->可执行文件。
- 函数执行时,会和调用它的脚本共用变量,也可以为函数设定局部变量及特殊位置参数。
- 在shell函数里面,return命令的功能与exit类似,return的作用是退出函数,而exit是退出脚本文件。
- return语句会返回一个退出值(即返回值)给调用函数的当前程序,而exit会返回一个退出值(即返回值)给执行程序的当前Shell
- 如果将函数存放在独立的文件中,被脚本加载使用时,需要使用source或“.”来加载。
- 在函数内一般使用local定义局部变量,这些变量离开函数后就会消失。
- 2)带参数的函数执行方法
函数名 参数1 参数2
- 注意:
- Shell的位置参数($1、
2...
、
2...、
2...、#、
∗
、
*、
∗、?及$@)都可以作为函数的参数来使用。
- 此时父脚本的参数临时地被函数参数所掩盖或隐藏。
- $0此时特殊,它仍然是父脚本的名称。
- 当函数执行完成时,原来的命令行脚本的参数即可恢复。
- 函数的参数变量是在函数体里面定义的。
4 Shell函数的基础实践
[root@backup ~]
herhan(){
echo "I am herhan."
}
function heh(){
echo "I am heh."
}
herhan
heh
5 利用Shell函数开发企业级URL检测脚本
[root@backup ~]
. /etc/init.d/functions
function usage(){
echo $"usage:$0 url"
exit 1
}
function check_url(){
wget --spider -q -o /dev/null --tries=1 -T 5 $1
if [ $? -eq 0 ];then
action "$1 is yes." /bin/true
else
action "$1 is no." /bin/false
fi
}
function main(){
if [ $# -ne 1 ];then
usage
fi
check_url $1
}
main $*
[root@backup ~]
www.baidu123.com is no. [失败]
[root@backup ~]
www.baidu.com is yes. [确定]
6 利用Shell函数开发一键优化系统脚本
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
curl -s -o /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
curl -s -o /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
sed -i 's/SELINUX=enforing/SELINUX=disabled' /etc/selinux/config
grep SELINUX=disabled /etc/selinux/config
setenforce 0
getenforce
systemctl disable firewalld
systemctl stop firewalld
systemctl status firewalld
systemctl list-unit-files | grep enable|egrep -v "sshd.service|crond.service|sysstat|rsyslog|^NetworkManager.service|irqbalance.service"|awk '{print "systemctl disable",$1}'|bash
systemctl list-unit-files |grep enable
useradd herhan
echo 123456|passwd --stdin herhan
\cp /etc/sudoers /etc/sudoers.ori
echo "herhan ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
tail -l /etc/sudoers
visudo -c
cp /etc/locale.conf{,.ori}
localectl set-locale LANG="zh_CN.UTF-8"
cat /etc/locale.conf
yum install ntpdate -y
/usr/sbin/ntpdate ntp3.aliyun.com
echo '#crond-id-001:time sync by herhan' >>/var/spool/cron/root
echo "*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com >/dev/null 2>&1">>/var/spool/cron/root
crontab -l
echo '* - nofile 65535 ' >>/etc/security/limits.conf
tail -l /etc/security/limits.conf
cat >>/etc/sysctl.conf<<EOF
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
EOF
sysctl -p
yum update -y
yum install tree nmap dos2unix lrzsz nc lsof wget tcpdump htop iftop iotop sysstat nethogs -y
yum install psmisc net-tools bash-completion vim-enhanced -y
[root@backup ~]
export PATH=$PATH:/bin:/sbin:/usr/sbin
if [ "$UID" != "0" ];then
echo "Please run this script by root."
exit 1
fi
SERVICE=`which service`
CHKCONFIG=`which chkconfig`
function mod_yum(){
if [ -e /etc/yum.repos.d/CentOS-Base.repo ];then
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup && \
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
fi
}
function close_selinux(){
sed -i 's/SELINUX=enforing/SELINUX=disabled' /etc/selinux/config
setenforce 0 &>/dev/null
}
function close_firewalld(){
systemctl disable firewalld
systemctl stop firewalld
}
function least_service(){
systemctl list-unit-files | grep enable|egrep -v "sshd.service|crond.service|sysstat|rsyslog|^NetworkManager.service|irqbalance.service"|awk '{print "systemctl disable",$1}'|bash
}
function adduser(){
if [ `grep -w herhan /etc/passwd|wc -l` -lt 1 ];then
useradd herhan
echo 123456|passwd --stdin herhan
\cp /etc/sudoers /etc/sudoers.ori
echo "herhan ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
tail -l /etc/sudoers
visudo -c &>/dev/null
fi
}
function charset(){
cp /etc/locale.conf{,.ori}
localectl set-locale LANG="zh_CN.UTF-8"
}
function time_sync(){
cron=/var/spool/cron/root
if [ `grep -w "ntpdate" $cron|wc -l` -lt 1 ];then
yum install ntpdate -y
echo '#crond-id-001:time sync by herhan' >>$cron
echo "*/5 * * * * /usr/sbin/ntpdate ntp3.aliyun.com >/dev/null 2>&1">>$cron
crontab -l
fi
}
function com_line_set(){
if [ `egrep "TMOUT|HISTSIZE|HISTFILESIZE" /etc/profile|wc -l` -lt 3 ];then
echo 'export TMOUT=300' >>/etc/profile
echo 'export HISTSIZE=5' >>/etc/profile
echo 'export HISTFILESIZE=5' >>/etc/profile
. /etc/profile
fi
}
function open_file_set(){
if [ `grep 65535 /etc/security/limits.conf|wc -l` -lt 1 ];then
echo '* - nofile 65535 ' >>/etc/security/limits.conf
tail -l /etc/security/limits.conf
fi
}
function set_kernel(){
if [ `grep kernel_flag /etc/sysctl.conf|wc -l` -lt 1 ];then
cat >>/etc/sysctl.conf<<EOF
net.ipv4.tcp_fin_timeout = 2
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_keepalive_time = 600
net.ipv4.ip_local_port_range = 4000 65000
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.tcp_max_tw_buckets = 36000
net.ipv4.route.gc_timeout = 100
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_synack_retries = 1
net.core.somaxconn = 16384
net.core.netdev_max_backlog = 16384
net.ipv4.tcp_max_orphans = 16384
net.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_max = 25000000
net.netfilter.nf_conntrack_tcp_timeout_established = 180
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
EOF
sysctl -p
fi
}
function init_ssh(){
\cp /etc/ssh/sshd_config /etc/ssh/sshd_config.`date +"%Y-%m-%d_%H-%M-%S"`
sed -i 's%#PermitRootLogin yes%PermitRootLogin no%' /etc/ssh/sshd_config
sed -i 's%#PermitEmptyPasswords no%PermitEmptyPasswords no' /etc/ssh/sshd_config
sed -i 's%#UseDNS yes%UseDNS no%' /etc/ssh/sshd_config
systemctl restart sshd
}
function update_linux(){
if [ `rpm -qa tree nmap dos2unix lrzsz nc lsof wget tcpdump htop iftop iotop sysstat nethogs psmisc net-tools bash-completion vim-enhanced|wc -l` -le 3 ];then
yum update -y
yum install tree nmap dos2unix lrzsz nc lsof wget tcpdump htop iftop iotop sysstat nethogs -y
yum install psmisc net-tools bash-completion vim-enhanced -y
fi
}
main(){
mod_yum
close_selinux
close_firewalld
least_service
adduser
charset
time_sync
com_line_set
open_file_set
set_kernel
init_ssh
update_linux
}
main
7 检测优化后的配合是否正常
[root@backup ~]
export PATH=$PATH:/bin:/sbin:/usr/sbin
if [ "$UID" != "0" ];then
echo "Please run this script by root."
exit 1
fi
. /etc/init.d/functions
function check_yum(){
Base=/etc/yum.repos.d/CentOS-Base.repo
if [ `grep aliyun $Base|wc -l` -ge 1 ];then
action "$Base config" /bin/true
else
action "$Base config" /bin/false
fi
}
function check_selinux(){
config=/etc/selinux/config
if [ `grep "SELINUX=disabled" $config|wc -l` -ge 1 ];then
action "$config config" /bin/true
else
action "$config config" /bin/false
fi
}
function check_service(){
export LANG=en
if [ `systemctl list-unit-files|grep enable|wc -l` -eq 7 ];then
action "sys service init" /bin/true
else
action "sys service init" /bin/false
fi
}
function check_open_file(){
limits=/etc/security/limits.conf
if [ `grep 65535 $limits|wc -l` -eq 1 ];then
action "$limits" /bin/true
else
action "$limits" /bin/false
fi
}
main(){
check_yum
check_selinux
check_service
check_open_file
}
main
8 利用Shell函数开发rsync服务启动脚本
[root@backup ~]
. /etc/init.d/functions
function usage() {
echo $"usage:$0 {start|stop|restart}"
exit 1
}
function start() {
rsync --daemon
sleep 1
if [ `netstat -lntup|grep rsync|wc -l` -ge 1 ];then
action "rsyncd is started." /bin/true
else
action "rsyncd is started." /bin/false
fi
}
function stop() {
killall rsync &>/dev/null
sleep 2
if [ `netstat -lntup|grep rsync|wc -l` -ge 0 ];then
action "rsync is stopped." /bin/true
else
action "rsync is started." /bin/false
fi
}
function main() {
if [ $# -ne 1 ];then
usage
fi
if [ "$1" = "start" ];then
start
elif [ "$1" = "stop" ];then
stop
elif [ "$1" = "restart" ];then
stop
sleep 1
start
else
usage
fi
}
main $*
[root@backup ~]
rsync is stopped. [ 确定 ]
rsyncd is started. [ 确定 ]
[root@backup ~]
rsyncd is started. [ 确定 ]
[root@backup ~]
rsync is stopped. [ 确定 ]