shell編程基礎(四): shell腳本語法之函數及調試


一、Shell腳本中的函數

和C語言類似,Shell中也有函數的概念,但是函數定義中沒有返回值也沒有參數列表。例如:

#! /bin/sh

fun(){ echo "Function fun is called";}
echo "-=start=-"
fun
echo "-=end=-"

注意函數體的左花括號'{'和后面的命令之間必須有空格或換行,如果將最后一條命令和右花括號'}'寫在同一行,命令末尾必須有;號。

在定義fun()函數時並不執行函數體中的命令,就像定義變量一樣,只是給fun這個名字一個定義,到后面調用fun函數的時候(注意Shell中的函數調用不寫括號)才執行函數體中的命令。Shell腳本中的函數必須先定義后調用,一般把函數定義都寫在腳本的前面,把函數調用和其它命令寫在腳本的最后(類似C語言中的main函數,這才是整個腳本實際開始執行命令的地方)。

Shell函數沒有參數列表並不表示不能傳參數,事實上,函數就像是迷你腳本,調用函數時可以傳任意個參數,在函數內同樣是用$0、$1、$2等變量來提取參數,函數中的位置參數相當於函數的局部變量,改變這些變量並不會影響函數外面的$0、$1、$2等變量。函數中可以用return命令返回,如果return后面跟一個數字則表示函數的Exit Status。

下面這個腳本可以一次創建多個目錄,各目錄名通過命令行參數傳入,腳本逐個測試各目錄是否存在,如果目錄不存在,首先打印信息然后試着創建該目錄。

編輯腳本
[root@VM_0_5_centos test]# vi tfun.sh 
查看腳本內容
[root@VM_0_5_centos test]# cat tfun.sh 
#! /bin/sh

is_directory()
{
  DIR_NAME=$1
  if [ ! -d $DIR_NAME ]; then
    return 1
  else
    return 0
  fi
}

for DIR in "$@"; do
  if is_directory "$DIR"
  then :
  else
    echo "Directory $DIR doesn't exist. Creating it now..."
    mkdir $DIR > /dev/null 2>&1
    if [ $? -ne 0 ]; then
      echo "Can't create directory $DIR"
      exit 1
    fi
  fi
done
運行測試腳本
[root@VM_0_5_centos test]# sh tfun.sh aaa abb acc add
Directory aaa doesn't exist. Creating it now...
Directory abb doesn't exist. Creating it now...
Directory acc doesn't exist. Creating it now...
Directory add doesn't exist. Creating it now...
查看是否成功創建目錄
[root@VM_0_5_centos test]# ll
total 20
drwxr-xr-x 2 root root 4096 Jul 16 11:16 aaa
drwxr-xr-x 2 root root 4096 Jul 16 11:16 abb
drwxr-xr-x 2 root root 4096 Jul 16 11:16 acc
drwxr-xr-x 2 root root 4096 Jul 16 11:16 add
-rw-r--r-- 1 root root  340 Jul 16 11:15 tfun.sh

注意:is_directory()返回0表示真返回1表示假。mkdir $DIR > /dev/null 2>&1這條語句時因為直接使用mkdir $DIR或mkdir $DIR > /dev/null可能會出錯,所以將可能出錯的情況都重定向輸出到/dev/null這個黑洞目錄當中。

二、Shell腳本的調試方法

Shell提供了一些用於調試腳本的選項,如下所示:

-n

讀一遍腳本中的命令但不執行,用於檢查腳本中的語法錯誤

-v

一邊執行腳本,一邊將執行過的腳本命令打印到標准錯誤輸出

-x

提供跟蹤執行信息,將執行的每一條命令和結果依次打印出來

使用這些選項有三種方法,一是在命令行提供參數

[root@VM_0_5_centos test]# sh -x tfun.sh a1 a2 a3
 1 [root@VM_0_5_centos test]# sh -x tfun.sh a1 a2 a3
 2 + for DIR in '"$@"'
 3 + is_directory a1
 4 + DIR_NAME=a1
 5 + '[' '!' -d a1 ']'
 6 + return 1
 7 + set -x
 8 + echo 'Directory a1 doesn'\''t exist. Creating it now...'
 9 Directory a1 doesn't exist. Creating it now...
10 + mkdir a1
11 + '[' 0 -ne 0 ']'
12 + set +x
13 + echo 'Directory a2 doesn'\''t exist. Creating it now...'
14 Directory a2 doesn't exist. Creating it now...
15 + mkdir a2
16 + '[' 0 -ne 0 ']'
17 + set +x
18 + echo 'Directory a3 doesn'\''t exist. Creating it now...'
19 Directory a3 doesn't exist. Creating it now...
20 + mkdir a3
21 + '[' 0 -ne 0 ']'
22 + set +x
第一種方法測試結果:

二是在腳本開頭提供參數

#! /bin/sh -x

第三種方法是在腳本中用set命令啟用或禁用參數

for DIR in "$@"; do
  if is_directory "$DIR"
  then :
  else
        set -x
        echo "Directory $DIR doesn't exist. Creating it now..."
        mkdir $DIR > /dev/null 2>&1
        if [ $? -ne 0 ]; then
          echo "Can't create directory $DIR"
          exit 1
        fi
        set +x
  fi
done
 1 [root@VM_0_5_centos test]# sh tfun.sh b bb bbb
 2 + echo 'Directory b doesn'\''t exist. Creating it now...'
 3 Directory b doesn't exist. Creating it now...
 4 + mkdir b
 5 + '[' 0 -ne 0 ']'
 6 + set +x
 7 + echo 'Directory bb doesn'\''t exist. Creating it now...'
 8 Directory bb doesn't exist. Creating it now...
 9 + mkdir bb
10 + '[' 0 -ne 0 ']'
11 + set +x
12 + echo 'Directory bbb doesn'\''t exist. Creating it now...'
13 Directory bbb doesn't exist. Creating it now...
14 + mkdir bbb
15 + '[' 0 -ne 0 ']'
16 + set +x
第三種方法測試結果:

set -x和set +x分別表示啟用和禁用-x參數,這樣可以只對腳本中的某一段進行跟蹤調試。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM