bash腳本之函數及循環特殊用法

一,概述

while的循環特殊用法(遍歷文件的每一行)
    while read line;do
        循環體
            done < /PATH/FROM/SOMEFILE
            
依次讀取/PATH/FROM/SOMEFILE文件中的每一行,且將行賦值給變量line



雙小括號方法,即((...))格式,也可以用于算術運算


雙小括號方法也可以使bash Shell實現C語言風格的變量操作
#I=10等價#((I++))

for循環的特殊格式:
for ((控制變量初始化;條件判斷表達式;控制變量的修正表達式))
do
    循環體
done

控制變量初始化:僅在運行到循環代碼段時執行一次
控制變量的修正表達式:每輪循環結束會先進行控制變量修正運算,而后再做條件判斷



select 循環與菜單
    
      select variable in list
          do
              循環體命令
          done
 
 select 循環主要用于創建菜單,按數字順序排列的菜單項將顯示在標準錯誤上,并顯示PS3提示符,等待用戶輸入
 
           
     用戶輸入菜單列表中的某個數字,執行相應的命令
     
     用戶輸入被保存在內置標量REPLY中.
     
          
select 是個無限循環,因此要記住用break命令退出循環,或用exit命令終止腳本.也可以按ctrl+c退出循環

select 經常和case 聯合使用

與for 循環類似,可以省略 in list ,此時使用位置參量


函數介紹
    函數functions是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程
    
    它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell程序的一部分.
    
    函數和shell程序比較相似,區別在于:
    
    shell程序在子shell中運行
    而shell函數在當前shell中運行.因此在當前shell中,函數可以對shell中變量進行修改
    
     
優先級別名-->函數-->內部命令-->外部命令


函數返回值

函數有兩種返回值:
函數的執行結果返回值:
1.使用echo或printf命令進行輸出
2.函數體中調用命令的輸出結果

函數的退出狀態碼:
1.默認取決與函數中執行的最后一條命令的退出狀態碼
2.自定義退出狀態碼,其格式為:
return 從函數中返回,用最后狀態命令決定返回值
return 0 無錯誤返回
return 1-255 有錯誤返回


交互式環境下定義和使用函數

$dir() {
 ls -l
}

定義該函數后,若在$后面鍵入dir,其顯示結果同ls-l的作用相同。
$dir

該dir函數將一直保留到用戶從系統退出,或執行了如下所示的unset命令:
$ unsetdir


在腳本中定義及使用函數


函數在使用前必須定義,因此應將函數定義放在腳本開始部分,直至shell首次發現它后才能使用


調用函數僅使用其函數名即可。

示例:
$cat func1
#!/bin/bash
# func1
hello()
{
echo "Hello there today's date is `date +%F`"
}
echo "now going to the function hello"
hello
echo "back from the function"


使用函數文件

可以將經常使用的函數存入函數文件,然后將函數文件載入shell


文件名可任意選取,但最好與相關任務有某種聯系。例如:functions.main

一旦函數文件載入shell,就可以在命令行或腳本中調用函數。可以使用set命令查看所有定義的函數,其輸出列表包括已經載入shell的所有函數。


若要改動函數,首先用unset命令從shell中刪除函數。改動完畢后,再重新載入此文件。


創建函數文件


函數文件示例:
$cat functions.main
#!/bin/bash
#functions.main
findit()
{
if [ $# -lt 1 ] ; then
echo "Usage:findit file"
return 1
fi
find / -name $1 –print
}


載入函數

函數文件已創建好后,要將它載入shell

定位函數文件并載入shell的格式:
. filename 或source filename

注意:此即<點> <空格> <文件名>
這里的文件名要帶正確路徑

示例:上例中的函數,可使用如下命令:
$ . functions.main



檢查載入函數

使用set命令檢查函數是否已載入。set命令將在shell中顯示所有的載入函數。

示例:
$set
findit=( )
{
if [ $# -lt 1 ]; then
echo "usage :findit file";
return 1
fi
find / -name $1 -print
}


執行shell函數
要執行函數,簡單地鍵入函數名即可:

示例:
$finditgroups
/usr/bin/groups
/usr/local/backups/groups.bak


刪除shell函數


現在對函數做一些改動。首先刪除函數,使其對shell不可用。使用unset命令完成此功能.
命令格式為:
unset function_name
實例:
$unset findit
再鍵入set命令,函數將不再顯示


函數參數


函數可以接受參數:
傳遞參數給函數:調用函數時,在函數名后面以空白分隔給定參數列表即可;例如“testfuncarg1 arg2 ...”
在函數體中當中,可使用$1, $2, ...調用這些參數;還可以使用$@, $*, $#等特殊變量


函數變量


變量作用域:
環境變量:當前shell和子shell有效
本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程;因此,本地變量的作用范圍是當前shell腳本程序文件,包括腳本中的函數。
局部變量:函數的生命周期;函數結束時變量被自動銷毀


注意:如果函數中有局部變量,如果其名稱同本地變量,使用局部變量。


在函數中定義局部變量的方法
local NAME=VALUE


函數遞歸實例

函數遞歸:
函數直接或間接調用自身
注意遞歸層數


遞歸實例:
階乘是基斯頓·卡曼于1808 年發明的運算符號,是數學術語
一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且有0的階乘為1。自然數n的階乘寫作n!。
n!=1×2×3×...×n。
階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。
n!=n(n-1)(n-2)...1
n(n-1)! = n(n-1)(n-2)!















1、寫個腳本:

  *
 ***
 *****
*******

blob.png

2、用until循環實現國際象棋棋盤

blob.png

3.掃描/etc/passwd文件每一行,如發現GECOS字段為空,則填充用戶名和單位電話為62985600,并提示該用戶的GECOS信息修改成功。

blob.png

4.利用for特殊格式打印出九九乘法表

blob.png

5.編寫函數實現數字的加減乘除運算,例如輸入1 + 2,,將得出正確結果

blob.png

    

6.階乘的表達式

blob.png

7.

斐波那契數列又稱黃金分割數列,因數學家列昂納多·斐波那契以兔子繁殖為例子而引入,故又稱為“兔子數列”,指的是這樣一個數列:0、1、1、2、3、5、8、13、21、34、……,斐波納契數列以如下被以遞歸的方法定義:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n≥2)

寫一個函數,求n階斐波那契數列

blob.png

8.漢諾塔(又稱河內塔)問題是源于印度一個古老傳說。大梵天創造世界的時候做了三根金剛石柱子,在一根柱子上從下往上按照大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規定,在小圓盤上不能放大圓盤,在三根柱子之間一次只能移動一個圓盤。

利用函數,實現N片盤的漢諾塔的移動步驟

blob.png

9.

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退出

blob.pngblob.png

10.編寫函數實現兩個數字做為參數,返回最大值

blob.png

11.

編寫服務腳本/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為當前腳本名

blob.png

blob.png

原創文章,作者:Kartik,如若轉載,請注明出處:http://www.www58058.com/41180

(1)
KartikKartik
上一篇 2016-08-29
下一篇 2016-08-29

相關推薦

  • mongodb及NoSQL入門學習總結

    分布式系統理論 一、 CAP: 分布式系統只能夠,滿足其中兩個? 1.?Consistency :?all nodes see the same data at the same time 一個節點修改后,需馬上復制到第二個節點。如果網絡故障,第二個節點將不能同步第一個節點更新的數據。這就是不能滿足一致性。 2.?Availibility:a guarant…

    2017-09-14
  • 優云老王(三)談埋點:人生處處有埋點

    說到埋點,的確是用戶最感興趣的話題之一,優云Web產品在內測階段便收到了用戶的各種反饋,反復問我無碼埋點是怎么做的。在此我專門與大家聊聊埋點以及各種實現方案的利弊。 1、埋點的來歷 先說下埋點的來歷,其實在互聯網沒流行起來之前,埋點并不是用來分析用戶行為的,技術人員為了解決某些問題,就在代碼里面加入了些行為邏輯代碼,如果用戶使用產品的過程中出了問題,就生成一…

    2016-09-19
  • CentOS6刪除/etc/fstab和/boot后恢復

    CentOS6刪除/etc/fstab和/boot后恢復 背景: Linux CentOS系統和啟動相關的文件都在/boot目錄下,如果我們將/boot目錄下所有的文件都刪除,然后在恢復系統,那以后在遇到系統啟動問題時就都可以解決了。在這基礎上,在將/etc/fstab文件刪除,這樣更加大了修復的難度,不過這都是可以修復的,這里就將介紹如何修復。 實驗環境:…

    2017-09-01
  • LVS中nat和dr的原理與用法簡述

      LVS中nat和dr的原理與用法簡述 lvs-nat:   多目標IP的DNAT,通過將請求報文中的目標地址和目標端口修改為某挑出的RS的RIP和PORT實現轉發; (1)RIP和DIP必須在同一個IP網絡,且應該使用私網地址;RS的網關要指向DIP; (2)請求報文和響應報文都必須經由Director轉發;Director…

    Linux干貨 2016-10-30
  • sed行編輯器

    Linux文本處理三劍客之一:sed(Stream Editor)流編輯器 sed:     將指定的文本文件內容逐行讀取至sed的臨時內存空間當中,稱為"模式空間",而后逐行查看是否被sed的地址定界所匹配到,如果匹配,則執行相應的編輯操作,否則,默認將模式空間中的內容打印至標準輸出  …

    Linux干貨 2016-08-15
欧美性久久久久