一、函數 1、簡介 Shell函數類似於Shell腳本,裡面存放了一系列的指令 不過,Shell的函數存在於記憶體,而不是硬碟文件,所以速度很快 另外,Shell還能對函數進行預處理,所以函數的啟動比腳本更快 2、定義 function 函數名() { 語句 [return] } 關鍵字functio ...
一、函數 1、簡介 Shell函數類似於Shell腳本,裡面存放了一系列的指令 不過,Shell的函數存在於記憶體,而不是硬碟文件,所以速度很快 另外,Shell還能對函數進行預處理,所以函數的啟動比腳本更快 2、定義 function 函數名() { 語句 [return] } 關鍵字function表示定義一個函數,可以省略,其後是函數名,有時函數名後可以跟一個括弧 符號“{”表示函數執行命令的入口,該符號也可以在函數名那一行,“}”表示函數體的結束,兩個大括弧之間是函數體 語句部分可以是任意的Shell命令,也可以調用其他的函數 在函數中使用 exit命令,可以退出整個腳本,通常情況,函數結束之後會返回調用函數的部分繼續執行 可以使用 break 語句來中斷函數的執行 函數的定義可以放到 .bash_profile 文件中,也可以放到使用函數的腳本中,還可以直接放到命令行中 函數可進行嵌套 可使用內部的unset命令刪除函數。一旦用戶註銷,Shell將不再保持這些函數 3、函數調用 3.1、命令行調用 # function show(){ --定義函數 show > echo "hello,you are calling the function" > } # function display() { --定義函數 display > echo "you display" > } # declare -f --顯示定義的函數清單 # declare -F --顯示定義的函數名清單 # show --命令調用函數 show # unset -f show --刪除 show 函數 3.2、腳本調用 # vim test.sh #!/bin/bash function show() { --定義函數 echo "hello shell,i am $1" } show george --調用函數,george 為傳遞參數 4、參數傳遞 函數可以通過位置變數傳遞參數。例如: 函數名 參數1 參數2 參數3 參數4 當函數執行時,$1 對應 參數1,其他依次類推 5、返回值 函數中的關鍵字“return”可以放到函數體的任意位置,通常用於返回某些值 Shell在執行到return之後,就停止往下執行,返回到主程式的調用行 return的返回值只能是0~256之間的一個整數,返回值將保存到變數“$?”中 # vim test.sh #!/bin/bash function abc() { RESULT=$(expr $1 \% 2) if [ "$RESULT" -ne "0" ];then return 1 else return 0 fi } echo "Please enter a number who can devide by 2" read N abc $N case $? in 0) echo "yes ,it is" ;; 1) echo "no ,it isn’t" ;; esac 6、函數的載入 如果函數在另外一個文件中,如 show 函數寫在了 function.sh 裡面了,我們就可以用 source 命令 # vim function.sh #!/bin/bash function show() { echo "hello world" } # vim test.sh #!/bin/bash source function.sh show # ./test.sh 7、變數作用域 預設情況下,變數具有全局作用域,如果想把它設置為局部作用域,可以在其前加入local;例如: local a="hello" 使用局部變數,使得函數在執行完畢後,自動釋放變數所占用的記憶體空間,從而減少系統資源的消耗,在運行大型的程式時,定義和使用局部變數尤為重要 二、函數實操 1、判斷 user 是否存在,若存在輸出其 shell;要求: 從命令行參數接受一個用戶名,根據該用戶是否存在而輸出相應的信息 腳本裡面定義一個函數,用於查詢用戶是否存在 定義另外一個函數,用於獲取用戶的 shell # vim test.sh #!/bin/bash exist() { if [ -z "$1" ]; then --函數內部的 $1 代表函數的第一個參數 echo "wrong parameter" >&2 return 1 fi local file=/etc/passwd --定義一個局部變數 grep -qE "^${1}:" $file return $? --函數返回一個值 } getshell() { if [ -z "$1" ]; then echo "wrong parameter" >&2 return 1 --返回非零,用於表示出錯 fi local file=/etc/passwd local line shell line=$(grep -E "^${1}:" $file) shell=${line##*:} echo $shell return 0 } if [ -z "$1" ];then --這裡的$1 不在函數中,代表的是腳本的第一個參數 echo "Usage: $(basename $0) <username>" >&2 exit 1 fi user=$1 if exist $user; then --調用函數 exist 就像調用普通命令一樣 echo "Shell of user $user: $(getshell $user)" --調用函數getshell else echo "user $user doesn't exist" fi 2、要求: 定義一個函數,用於查詢某個用戶的最後登錄時間 要求在函數中出現的變數必須是本地變數 如果查詢到結果,函數應該返回真值,否則,應該返回假值 如果能夠查到記錄,就輸出記錄,否則就輸出相應的出錯信息 # vim test.sh #!/bin/bash help() { echo "Usage: user_last <name>" >&2 } last_log() { local time time=$(lastlog -u ${username} | tail -n1 | awk '{print $(NF-5),$(NF-4),$(NF-3),$(NF-2),$(NF-1),$NF}') if [ -z "$time" ];then echo "no record" return 1 else echo "last login time of user $username: $time" return 0 fi } if [ -z "$1" ]; then help exit 1 fi username=$1 last_log 三、基本調試方法 1、bash -x --把所執行的命令及其參數列印到標準錯誤 2、bash -n --讀取命令,但不執行,可用於檢查語法的正確性;但不能檢查具體的邏輯正確性 3、縮小代碼範圍 --刪除部分代碼,或者註釋掉部分代碼,以縮小問題的範圍;可以使用Here document 快速地註釋一部分代碼: :<< 'DEBUG' command...... DEBUG