函数:
把一段独立功能的代码当作一个整体,并命名一个名字;命名的代码段,此即为函数
由若干条shell命令组成的语句块,实现代码重用和模式化编程
函数的作用:
在某些场景下,我们可以将独立功能的一段代码定义为一个函数,用到此功能时,直接调用函数即可,而不必重复编写代码,节省一定的代码量
注意:定义函数的代码段不会自动执行,在调用时执行;所谓调用函数,在代码中给定函数名即可;
函数名出线的任何位置,在代码执行时,都会被自动替换为函数代码
语法格式:
语法一:
function f_name() {
函数代码
…
}
语法二:
f_name() {
函数代码
…
}
函数的定义:
在交互式环境下定义函数,定义完成后,直接调用即可
把函数定义在脚本中,当中脚本的一部分
存放在特定的函数文件当中,用到时直接调用函数文件
函数的生命周期:每次被调用时创建,返回时终止
函数的退出状态码:
其状态返回结果为函数体中运行的最后一条命令的状态结果
自定义状态返回值,需要使用:return
return [0-255]
0:成功
1-255:失败
函数返回值:
函数的执行结果返回值:
(1) 使用echo或printf命令进行输出
(2)函数体中调用的命令执行结果
函数的退出状态码:
(1)默认取决于函数体中执行的最后一条命令的退出状态码
(2)自定义:return
函数可以接受参数:
在函数体当中,可以使用$1,$2,…引用传递给函数的参数;还可以在函数中使用$*或$@引用所有参数,$#引用传递参数的个数
在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,func arg1 arg2 arg3…
使用函数文件:
可以将经常使用的函数存放在一个文件当中,然后将函数文件载入shell程序执行,一旦函数载入shell,就可以在命令行或脚本中调用函数
可使用set命令查看当前shell所载入的所有函数
使用unset命令可删除所指定的函数
载入函数文件:
. filename或source filename
变量作用域:
环境变量:生效范围为当前shell以及子shell进程
本地变量:生效范围为当前shell进程,随着shell进程结束而结束
局部变量:生效范围为脚本中某一代码片段,随着函数的结束而结束
建议在函数当中使用局部变量,因为函数是在当前shell进程中执行的,函数中所定义的变量有可能会和脚本中的变量产生冲突
因此把函数中变量定义为局部变量,只在函数内部中生效
局部变量定义方法;
local NAME="value"
示例:
1.编写服务脚本/root/bin/testsrv.sh,完成如下要求
(1) 脚本可接受参数:start, stop, restart, status
(2) 如果参数非此四者之一,提示使用格式后报错退出
(3) 如是start:则创建/var/lock/subsys/SCRIPT_NAME, 并显示“启动成功”
考虑:如果事先已经启动过一次,该如何处理?
(4) 如是stop:则删除/var/lock/subsys/SCRIPT_NAME, 并显示“停止完成”
考虑:如果事先已然停止过了,该如何处理?
(5) 如是restart,则先stop, 再start
考虑:如果本来没有start,如何处理?
(6) 如是status, 则如果/var/lock/subsys/SCRIPT_NAME文件存在,则显示“SCRIPT_NAMEis running…”
如果/var/lock/subsys/SCRIPT_NAME文件不存在,则显示“SCRIPT_NAME is stopped…”
其中:SCRIPT_NAME为当前脚本名
[root@CentOS7 ~]# cat service.sh #!/bin/bash # NAME=$(basename $0) SCRIPTS="/var/lock/subsys/$NAME" function start() { if [ ! -e $SCRIPTS ];then touch $SCRIPTS sleep 1 echo "start service $NAME finished." else echo "$NAME service is running..." fi } function stop() { if [ -e $SCRIPTS ];then rm -f $SCRIPTS sleep 1 echo "stop service $NAME finished." else echo "service $NAME is not running..." fi } function restart() { if [ -e $SCRIPTS ];then rm -f $SCRIPTS touch $SCRIPTS sleep 1 echo "restart service $NAME finished." else touch $SCRIPTS sleep 1 echo "start service $NAME finished." fi } function status() { if [ -e $SCRIPTS ];then echo "service $NAME is running..." else echo "service $NAME is not running..." fi } function error() { echo "Usage: `basename $0` {start|stop|restart|status}" exit 1 } case $1 in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) error ;; esac [root@CentOS7 ~]# ./service.sh start #启动服务器 start service service.sh finished. [root@CentOS7 ~]# ./service.sh stop #停止服务 stop service service.sh finished. [root@CentOS7 ~]# ./service.sh restart #如果服务处于停止状态,则启动服务 start service service.sh finished. [root@CentOS7 ~]# ./service.sh restart #如果服务处于启动状态,则重启服务 restart service service.sh finished. [root@CentOS7 ~]# ./service.sh status #当前服务运行状态为启动 service service.sh is running... [root@CentOS7 ~]# ./service.sh stop #服务运行状态为未启用 stop service service.sh finished. [root@CentOS7 ~]# ./service.sh status service service.sh is not running... [root@CentOS7 ~]#
2.编写脚本/root/bin/copycmd.sh
(1) 提示用户输入一个可执行命令名称
(2) 获取此命令所依赖到的所有库文件列表
(3) 复制命令至某目标目录(例如/mnt/sysroot)下的对应路径下;
如:/bin/bash ==> /mnt/sysroot/bin/bash
/usr/bin/passwd==> /mnt/sysroot/usr/bin/passwd
(4) 复制此命令依赖到的所有库文件至目标目录下的对应路径下:
如:/lib64/ld-linux-x86-64.so.2 ==> /mnt/sysroot/lib64/ld-linux-x86-64.so.2
(5)每次复制完成一个命令后,不要退出,而是提示用户键入新的要复制的命令,并重复完成上述功能;直到用户输入quit退出
[root@CentOS7 bin]# cat copycmd.sh #!/bin/bash # function copycmd() { local MKDIR=$DIR$(which --skip-alias $CMD | grep -E -o "^/.*/") [ ! -e $MKDIR ] && mkdir -p $MKDIR cp `which --skip-alias $CMD` $MKDIR [ $? -eq 0 ] && echo "Copy $CMD command file finished." } function copylib() { [ ! -e $DIR$LIB ] && mkdir -p $DIR$LIB local LIBFILE=$(ldd `which --skip-alias $CMD` | grep -E -o "/.*" | sed -r 's@(.*) .*@\1@') cp $LIBFILE $DIR$LIB [ $? -eq 0 ] && echo "Copy $CMD command lib file finished." } DIR="/mnt/sysroot" LIB="/lib64/" read -p "请输入一个可执行命令:" CMD until [ $CMD == "quit" ] do if ! which --skip-alias $CMD &> /dev/null;then echo "$CMD不是一个可执行命令" read -p "请输入一个可执行命令:" CMD continue fi copycmd copylib read -p "请输入一个可执行命令:" CMD done [root@CentOS7 bin]# bash copycmd.sh 请输入一个可执行命令:ls Copy ls command file finished. Copy ls command lib file finished. 请输入一个可执行命令:passwd Copy passwd command file finished. Copy passwd command lib file finished. 请输入一个可执行命令:useradd Copy useradd command file finished. Copy useradd command lib file finished. 请输入一个可执行命令:quit [root@CentOS7 sysroot]# cd /mnt/sysroot/ [root@CentOS7 sysroot]# cd [root@CentOS7 ~]# cd /mnt/sysroot/ [root@CentOS7 sysroot]# ls lib64 usr [root@CentOS7 sysroot]# ls lib64/ usr/sbin/ usr/bin/ #查看命令文件和库文件是否复制成功 lib64/: ld-linux-x86-64.so.2 libcap.so.2 libfreebl3.so libpam_misc.so.0 libselinux.so.1 libacl.so.1 libcrypt.so.1 libglib-2.0.so.0 libpam.so.0 libsemanage.so.1 libattr.so.1 libc.so.6 libgmodule-2.0.so.0 libpcre.so.1 libsepol.so.1 libaudit.so.1 libdl.so.2 libgobject-2.0.so.0 libpopt.so.0 libuser.so.1 libbz2.so.1 libffi.so.6 liblzma.so.5 libpthread.so.0 libustr-1.0.so.1 usr/bin/: ls passwd usr/sbin/: useradd [root@CentOS7 sysroot]#
原创文章,作者:zhai796898,如若转载,请注明出处:http://www.178linux.com/39743