1. 函数function的作用
-
函数function是由若干条shell命令组成的语句块,实现代码重用和模块化编程。
-
它与shell程序形式上是相似的,不同的是它不是一个单独的进程,不能独立运 行,而是shell程序的一部分,定义函数只对当前的会话窗口有效,如果再打开一个窗口再定义另外一个函数,就对另一个窗口有效,两者互不影响。
-
函数和shell程序比较相似,区别在于以下两种:
- Shell程序在子Shell中运行。
- 而Shell函数在当前Shell中运行,因此在当前Shell中,函数可以对shell中变量进行修改。
2. 函数的定义
- 函数由两部分组成:函数名和函数体
例子:
[root@ansible ~]# vim test.sh
#!/bin/bash
function maqiang(){
echo "hehe"
}
maqiang 如果函数定义了,但其没有调用则不会执行。这里使用名字调用
[root@ansible ~]# bash -n test.sh
[root@ansible ~]# bash -x test.sh 执行
+ maqiang
+ echo hehe
hehe
[root@ansible ~]# bash test.sh
hehe
3. 函数参数
- 当传递参数时
[root@ansible ~]# vim test.sh
#!/bin/bash
function my_service(){
case $1 in
"start")
echo "start $2"
;;
"stop")
echo "stop $2"
;;
"restart")
echo "restart $2"
;;
"status")
echo "status $2"
;;
*)
echo "Usage: service $2 start|stop|restart|status"
;;
esac
}
my_service jjyy httpd 传递第一个参数$1,要么是start/stop/restart/status,否则打印最后一行内容,这里给的是jjyy,则一定会打印最后一行。传递第二个参数为httpd
[root@ansible ~]# bash -x test.sh
+ my_service jjyy httpd
+ case $1 in
+ echo 'Usage: service httpd start|stop|restart|status'
Usage: service httpd start|stop|restart|status
- 当没有传递参数时
[root@ansible ~]# vim test.sh
#!/bin/bash
function my_service(){
case $1 in
"start")
echo "start $2"
;;
"stop")
echo "stop $2"
;;
"restart")
echo "restart $2"
;;
"status")
echo "status $2"
;;
*)
echo "Usage: service $2 start|stop|restart|status"
;;
esac
}
my_service
[root@ansible ~]# bash test.sh
Usage: service start|stop|restart|status 没有传递参数时,$1匹配的*,则打印的Usage。$2没有匹配任何东西
4. 在函数里用本地变量
- 当不调用a=10时,则不打印10
[root@ansible ~]# vim a.sh
#!/bin/bash
function test(){
local a=10
echo $a
}
echo $a 此$a跟a=10不是一码事
[root@ansible ~]# bash -x a.sh
+ echo
[root@ansible ~]# bash a.sh
[root@ansible ~]#
- 在脚本前加a=20时,则打印20
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=10
echo $a
}
echo $a
[root@ansible ~]# bash a.sh
20
- 当调用函数时,则打印20
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=10 此a=10只能在函数里用,与上面的a=20毫不相干
}
test 调用此函数
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ local a=10
+ echo 20
20
- 当在函数里添加$a时,则先打印10,后打印20
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=10
echo $a
}
test 先调用函数则会先执行函数里的$a,所以先打印10.后执行下面的$a则后打印20
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ local a=10
+ echo 10
10
+ echo 20
20
- 当在函数外另添加a=30,则会覆盖之前的20,先打印10,后打印30
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=10
echo $a
}
a=30
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ a=30
+ test
+ local a=10
+ echo 10
10
+ echo 30
30
- 当在函数里新加一个50,则会覆盖函数里之前的值
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=10
a=50 该50会覆盖10,并不会影响函数外的a=20
echo $a
}
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ local a=10
+ a=50
+ echo 50
50
+ echo 20
20
- 当函数里没有local时,则函数里的值会覆盖函数外的值
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
a=10
echo 50
}
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ a=10
+ echo 50
50
+ echo 10
10
- 当在函数里多加个local a=30时,该30会被50覆盖,则先打印50,后打印40
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
a=40
local a=30
echo 50
}
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ a=40
+ local a=30
+ echo 50
50
+ echo 40
40
- 当在函数里先定义a=40时,则该40会覆盖全局变量。再定义local a=30,则先打印函数里的值后打印函数外的值
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
a=40
local a=30
echo $a
}
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ a=40
+ local a=30
+ echo 30
30
+ echo 40
40
- 当先local定义a=30,后定义a=40时,则40不会覆盖全局变量,值覆盖函数里之前定义的变量。所以先打印40,后打印20
[root@ansible ~]# vim a.sh
#!/bin/bash
a=20
function test(){
local a=30
a=40
echo $a
}
test
echo $a
[root@ansible ~]# bash -x a.sh
+ a=20
+ test
+ local a=30
+ a=40
+ echo 40
40
+ echo 20
20
5. 生成证书
[root@ansible ~]# ls
a.sh cerfication.sh test.sh
[root@ansible ~]# vim cerfication.sh
#!/bin/bash
if [ $UID -ne 0 ];then
echo "请以管理员身份运行此脚本。"
exit 120
fi
if [ ! -d /etc/pki/CA ];then
mkdir -p /etc/pki/CA
fi
cd /etc/pki/CA
if [ ! -d private ];then
mkdir -p private
fi
(umask 077;openssl genrsa -out private/cakey.pem 2048)
/usr/bin/expect <<EOF
spawn openssl req -new -x509 -key private/cakey.pem -out cacert.pem -days 365
expect {
"*code" {send "CN\n"; exp_continue}
"Province" {send "HB\n"; exp_continue}
"*city" {send "WH\n"; exp_continue}
"*Company" {send "www.example.com\n"; exp_continue}
"*section" {send "www.example.com\n"; exp_continue}
"*hostname" {send "www.example.com\n"; exp_continue}
"*Address" {send "1@2.com\n"}
}
expect eof
EOF
mkdir certs newcerts crl &>/dev/null
touch index.txt && echo 01 > serial
cd
(umask 077;openssl genrsa -out httpd.key 2048)
/usr/bin/expect <<EOF
spawn openssl req -new -key httpd.key -days 365 -out httpd.csr
expect {
"*code" {send "CN\n";exp_continue}
"*Province" {send "HB\n";exp_continue}
"*city" {send "WH\n";exp_continue}
"*Company" {send "www.example.com\n";exp_continue}
"*section" {send "www.example.com\n";exp_continue}
"*hostname" {send "www.example.com\n";exp_continue}
"*Address" {send "1@2.com\n";exp_continue}
"*password" {send "\n";exp_continue}
"An*" {send "\n"}
}
expect eof
EOF
/usr/bin/expect <<EOF
spawn openssl ca -in httpd.csr -out httpd.crt -days 365
expect {
"Sign*" {send "y\n";exp_continue}
"*commit" {send "y\n"}
}
expect eof
EOF
[root@ansible ~]# ls
a.sh httpd.crt httpd.key
cerfication.sh httpd.csr test.sh