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.www58058.com/39023

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

相關推薦

  • 如何使用正則表達式

    正則表達式(Regular Expression)就是使用簡單的字符按照預先設定的規則來完成復雜的功能,說白了,正則表達式是一種字符串的匹配方式,就是用預先設定好的規則來描述我們想要表達的內容,它是由普通字符以及元字符組成的字符串,其中元字符不表示本身的意義,而是用于表達控制或通配等功能。 為什么要用這個東西那,我想,每一個學習計算機的人都應該明白,計算機就…

    Linux干貨 2015-10-27
  • 第二周作業

    linux 文件管理命令 rm、mv、cp rm rm命令:remove rm [OPTION]… FILE… 常用選項: -i:interactive (默認rm是‘rm -i’的別名) -f:force -r: recursive        &nb…

    Linux干貨 2016-12-08
  • rsync+inotify實現數據實時備份

    rsync+inotify實現數據實時備份 §·rsync簡單介紹 1 §·什么是rsync 1 §·rsync的功能特性 1 §·rsync的優點和不足 2 §·初識inotify 2 §·rsync命令工作模式 2 §·rsync常用命令選項 3 §·配置rsync以守護進程的方式運行 3 ※·安裝并啟動 xinetd 3 ※·為rsync服務器提供配置…

    Linux干貨 2016-10-30
  • find 命令詳解

    Find 命令詳解 find:   實時查找工具, 通過遍歷指定路徑完成文件查找;   工作特點:     查找速度略慢     精確查找     實時查找 可能只搜索用戶具備讀取和執行權限的目錄   語法:   find [OP…

    2017-04-09
  • MySQL-MMM實現MySQL高可用讀寫分離

    實驗環境 實驗拓撲 主機配置環境說明 主機名 IP地址 角色/用途 MySQL Server_ID master1 192.168.80.101 MySQL主節點,可讀寫操作 11 master2 192.168.80.102 MySQL備節點,可讀寫操作 12 slave1 192.168.80.103 MySQL從節點,僅能讀 13 slave2 192…

    Linux干貨 2016-06-01
  • 少走冤枉路!帶你走過SNMP的那些坑

    SNMP(Simple Network Management Protocol)即簡單網絡管理協議,是在網絡與系統監控領域中,最常使用的一種數據采集技術。盡管這個協議非常簡單,但在大規模IT環境監測中,還是經常會碰到各種坑,因此優云開源了一套友好的SNMPAPI,并通過本文簡單介紹這套API中的一些特點,希望幫助各位運維同仁提前規避一些問題。 特點[0].&…

    2016-06-22
欧美性久久久久