bash 循环和函数

回顾: 循环

循环控制:break,continuewhile , for循环的特殊用法for (());do
    循环体donewhile read VARAIBLE;do
    循环体done < /PATH/FROM/SOMEFILE

bash脚本编程:

case语句:
    
    多分支语句:        if CONDITION1;then
            分支1
        elif CONDITION2;then
            分支2
        ...        else CONDITION;then
            分支n        fi

示例1:显示一个菜单给用户; cpu)display cpu information mem)display memory information disk)display disks information quit)quit

要求:(1)提示用户给出选择; (2)正确的选择则给出相应的信息;否则,提示重新选择正确的选项

#!/bin/bash##cat << EOF
cpu) display cpu information
mem) display memory infomration
disk) display disks information
quit) quit
=====================
EOFread -p "Enter your option:" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do
        echo "cpu,mem,disk,quit"
        read -p "Enter your option again:" optiondoneif [ "$option" == "cpu" ];then
        lscpuelif [ "$option" == "mem" ];then
        free -melif [ "$option" == "disk" ];then
        df -helif [ "$option" == "quit" ];then
        exitfi

case语句的语法格式:只适用于一个变量反复跟多个字符串等值或者不等值比较时,来匹配。

case $VARAIBLE inPAT1)
    分支1
    ;;
PAT2)
    分支2
    ;;
*)
    分支n
    ;;
esac

示例1 使用上边的脚本,把通过if的代码,来用case语句实现

#!/bin/bash##cat << EOF
cpu) display cpu information
mem) display mem information
disk) display disks information
quit) exitEOFread -p "Enter your option :" optionwhile [ "$option" != "cpu" -a "$option" != "mem" -a "$option" != "disk" -a "$option" != "quit" ]do
        echo "cpu,mem,disk,quit"
        read -p "Enter your option again :" optiondonecase $option incpu)
        lscpu
;;
mem)
        free -m
;;
disk)
        df -h
;;
quit)        exit;;esac

示例2:写一个服务框架脚本;

$lockfile,值/home/soft/SCRIPT_NAME

(1)此脚本可接受start,stop,restart,status四个参数之一;

(2)如果参数非此四者,则提示使用帮后退出;

(3)start,则创建lockfile,并显示启动;stop,则删除lockfile,并显示停止;restart,则先删除文件在创建此文件,而后显示重启完成;status,如果lockfile存在,则显示running,否则,则显示为stopped。

#!/bin/bash#prog=$(basename $0)
lockfile=/home/soft/$progcase $1 instart)        if [ -f $lockfile ];then
                echo "$prog is running"
        else
                touch $lockfile
                [ $? -eq 0 ] && echo "start $prog finshed"
        fi
        ;;
stop)        if [ -f $lockfile ];then
                rm -f $lockfile
                [ $? -eq 0 ] && echo "stop $prog finshed"
        else
                echo "$prog is not running"
        fi
        ;;
restart)        if [ -f $lockfile ];then
                rm -f $lockfile
                touch $lockfile
                echo "$prog is restart"
                        else
                touch -f $lockfile
                echo "start $prog finshed"
        fi
        ;;
status)        if [ -f $lockfile ];then
                echo "$prog is running"
        else
                echo "$prog is stopped"
        fi
        ;;
*)        echo "Usage: $prog {start|stop|restart|status}"
        exit 1esac

函数:function

过程是编程:代码重用
        
        模块化编程
        结构化编程
把一段独立功能的代码当做一个整体,并为之一个名字;命名的代码段,此即为函数;
注意:定义函数的代码段不会自动执行,再调用时执行;所谓调用函数,在代码中给定函数名即可;函数名出现的任何位置,在代码执行时,都会被自动替换为函数代码;

语法一

function f_name { …函数体… }

语法二

f_name() { …函数体… }

函数的生命周期:每次被调用时创建,返回时终止;

其状态返回结果为函数体重运行的最后一条命令的状态结果;
自定义状态返回值,需要使用:returnreturn[0-255]0是成功1-255失败

示例1:给定一个用户名,取得用户Id号和默认shell;

正常不用函数来写这段代码的话是这样的

#!/bin/bash#if id "$1" &> /dev/null ;then
        grep "^$1\>" /etc/passwd | cut -d: -f 3,7else
        echo "NO such user"fi

用函数来定义 注意:函数里边不能直接用$1..来直接充当参数。

#!/bin/bash#if id "$1" &> /dev/null ;then
        grep "^$1\>" /etc/passwd | cut -d: -f 3,7else
        echo "NO such user"fi[root@centous1 lianxi]# bash +x user2.sh user1^C

这个时候直接运行时是没有结果的,我们需要调用这个函数。

#!/bin/bash#userinfo() {        if id "$username" &> /dev/null;then
        grep "^$username\>" /etc/passwd |cut -d: -f 3,7else
        echo "NO such user"fi}
username=$1userinfo


[root@centous1 lianxi]# bash +x user2.sh user14323:/bin/bash

同时,我们还可以多次调用

#!/bin/bash#userinfo() {        if id "$username" &> /dev/null;then
        grep "^$username\>" /etc/passwd |cut -d: -f 3,7else
        echo "NO such user"fi}
username=$1userinfo
username=$2userinfo


[root@centous1 lianxi]# bash +x user2.sh user1 user24323:/bin/bash4324:/bin/bash

示例2:把前边的服务脚本用函数来编写

#!/bin/bash#prog=$(basename $0)
lockfile=/home/soft/$progstart (){        if [ -f $lockfile ];then
                echo "$prog is running"
        else
                touch $lockfile
                [ $? -eq 0 ] && echo "start $prog finshed"
        fi}stop (){        if [ -f $lockfile ];then
                rm -f $lockfile
                [ $? -eq 0 ] && echo "stop $prog finshed"
        else
                echo "$prog is not running"
        fi}status () {        if [ -f $lockfile ];then
                echo "$prog is running"
        else
                echo "$prog is stopped"
        fiusage () {        echo "Useage: $lockfile { start|stop|restart|status}"}case $1 instart)
        start
;;
stop)
        stop
;;
restart)
        stop
        start
;;
status)
        status
;;
*)
        usageesac[root@centous1 lianxi]# bash +x testdir3.sh startstart testdir3.sh finshed
[root@centous1 lianxi]# bash +x testdir3.sh stopstop testdir3.sh finshed
[root@centous1 lianxi]# vim testdir3.sh[root@centous1 lianxi]# bash +x testdir3.sh stoptestdir3.sh is not running
[root@centous1 lianxi]# bash +x testdir3.sh stUseage: /home/soft/testdir3.sh { start|stop|restart|status}

函数返回值:

函数执行结果返回值:

    (1)使用echo或printf命令进行输出;

(2)函数体重调用的命令的执行结果;

函数的退出状态码:

(1)默认取决于函数体重执行的最后一条命令的退出状态码;

(2)自定义:return

函数可以接收参数:

传递参数给函数:
    
    在函数体中,可以使用$1,$2...医用传递给函数的参数;还可以在函数
中使用$* $@引用所有参数,$#引用传递的参数个数

在调用函数时,在函数名后面以空白符分隔给定参数列表即可,例如,arg1 arg2

再这里应该注意的是,一个脚本中需要使用$1,$2…时,注意,如果其中有函数,那么函数会直接调用,而不是经过脚本之后再调用。

示例;添加10个用户, 添加用户的功能使用函数实现,用户名作为参数传递给函数;

#!/bin/bash##addusers(){        if id $1 &> /dev/null;then
                return 5
        else
                useradd $1
                retval=$?                return $retval
        fi}for i in {1..10};do
        addusers ${1}${i}
        retval=$?        if [ $retval -eq 0 ];then
                echo "Add user ${1}${i} finshed"
        elif [ $retval -eq 5 ];then
                echo "user ${1}${i} exists."
        else
                echo "Unkown Error"
        fidone[root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1
+ id abc1
+ useradd abc1
+ retval=0+ return 0+ '[' 0 -eq 0 ']'+ echo 'Add user abc1 finshed'.....
.....

[root@centous1 lianxi]# bash -x userAD.sh abc+ for i in '{1..10}'+ addusers abc1
+ id abc1
+ return 5+ retval=5+ '[' 5 -eq 0 ']'+ '[' 5 -eq 5 ']'+ echo 'user abc1 exists.'....
....

变量作用域:

局部变量:

作用域的函数的生命周期;在函数结束时被自动销毁;

定义局部变量的方法:local VARIABLE=VALUE

本地变量:作用域是运行脚本的shell进程的生命周期;因此,其作用域是脚本程序文件。

用例子来说明

#!/bin/bash#name=tomsetname(){
        name=jarry        echo "$name"}
setnameecho "$name"~

[root@centous1 lianxi]# bash -x 123.sh+ name=tom
+ setname
+ name=jarry
+ echo jarry
jarry
+ echo jarry
jarry#!/bin/bash#name=tomsetname(){        local name=jarry        echo "$name"}
setnameecho "$name"[root@centous1 lianxi]# bash -x 123.sh+ name=tom
+ setname
+ local name=jarry
+ echo jarry
jarry
+ echo tom
tom

原创文章,作者:forest,如若转载,请注明出处:http://www.178linux.com/39023

(0)
forestforest
上一篇 2016-08-24 11:20
下一篇 2016-08-24 11:20

相关推荐

  • CentOS安装本地 YUM源 产生的问题和解决过程

    本人刚刚踏入Linux的神秘殿堂就被如何安装软件这样的问题难倒了,经过Google大神的指点,终于找到了如何配置YUM源的方法,其中也不是一帆风顺,也产生了一些小问题,这些都是基础知识,希望能够帮到刚刚学习Linux的朋友。     由于VMware的终端不好用,所以想换成XShell,过程中又需要配置网络属性,桥接到…

    Linux干货 2016-01-05
  • 推荐-内核虚拟化技术——LXC初体验

    一、Cgroups 1.1 介绍 Cgroup是Control group的简称。最初由由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年以“process containers(进程容器)”的名字开始的, 在2007年的晚些时候被重命名为“控制组”并被合并到了2.6.24版的内核中,现已成为Linux内核中的一个功能,…

    Linux干货 2016-03-31
  • Linux中的文件管理命令及shell特性

    Linux中的文件管理命令 一、linux中的目录管理命令:mkdir和rmdir mkdir命令:创建目录 – SYNOPSIS         mkdir [OPTION]… DIRECTORY…     -…

    Linux干货 2016-09-27
  • Linux下常用压缩工具总结

    gzip: 1)只能针对普通文件进行压缩,对文件夹、符号链接无效。 2)如果想对多个文件一起压缩并打包,gzip是无法办到的,需要结合tar进行 [root@mysql-master databackup]# ll 总用量 32 drwx—— 2 root root 4096&nb…

    Linux干货 2016-12-05
  • SSH——安全的通信

    SSH ·ssh:secure shell, protocol, 22/tcp,  安全的远程登录 ·OpenSSH:ssh协议的开源实现 ·dropbear:另一个开源实现 ·SSH协议版本:          v1:基于CRC-32做MAC,不安全;man-in-m…

    Linux干货 2016-09-25
  • 磁盘文件挂载与卸载

    挂载(mount)何为挂载?挂载指将文件系统与根文件系统的某个现存的目录建立起来的关联关系,这样我们就可以将目录作为访问磁盘文件的入口,进行存取交互。挂载点:挂载点指的是被挂载的对象,通常挂载点是一个目录,不过有时候也有文件作为挂载点格式:mount 设备 挂载点 ;此挂载方法味临时挂载,只在当前的shell中有效,退出则清除挂载关联设备文件在/dev/sd…

    Linux干货 2017-04-24