首頁 > 軟體

linux shell 程式設計之函數使用詳解

2022-10-30 14:01:10

前言

使用linux的shell程式設計,可以說函數是非常重要的內容,也是在編寫各類shell指令碼的時候經常用到的,本篇將介紹下函數相關的使用。

shell 函數分類

  • 系統函數
  • 自定義函數

系統函數

系統函數為linux自帶的函數, 可以在shell編寫中直接使用。下面介紹幾種常用的系統函數

1、basename

用於獲取檔名函數, 根據給出的檔案路徑擷取出檔名;

語法

basename [string / pathname] [suffix]  

  • 根據根據指定字串或路徑名進行擷取檔名, 比如: 根據路徑"/root/shells/aa.txt", 可以擷取出aa.txt;
  • suffix: 用於擷取的時候去掉指定的字尾名;

簡單案例

比如在當前目錄下,有一個叫ch1.sh的檔案,使用該命令的效果如下

該命令的用途

  • 遍歷某個檔案目錄之後,可以使用該命令拿到該目錄下的檔名稱做後續處理;
  • 拿到檔名稱之後,更改某個匹配的檔案的許可權等;

2、dirname

從指定檔案的絕對路徑, 去除檔名,返回剩下的字首目錄路徑

語法

dirname 檔案絕對路徑

簡單案例

更多的系統函數,可以使用: declare -f 命令進行檢視

自定義函數

shell程式設計人員可以通過自定義開發函數,實現程式碼重用,提升模組的封裝性、可讀性以及可維護性;

語法

# 函數的定義
[ function ] funname ()
{
    命令
    [return 返回值]

}

# 呼叫函數
funname 傳遞引數1 傳遞引數2 ...

語法說明

  • 可以帶function fun() 定義,也可以直接fun() 定義,不帶任何引數;
  • 引數返回,可以顯示加:return 返回,如果不加,將以最後一條命令執行結果,作為返回值, return後跟數值n(0~255);

注意點

必須在呼叫函數地方之前,先宣告函數再呼叫,shell指令碼是逐行執行的, 只有先執行了函數, 後面的動作才可以使用函數;

案例1:無參無返回值函數

#!/bin/bash
hello(){
        echo "hello func"
}
hello

呼叫下這個指令碼,觀察效果展示

案例2:無參有返回值函數

#! /bin/bash
function sum(){
    echo "求兩個數的和..."
    read -p "請輸入第一個數位: " n1
    read -p "請輸入第二個數位: " n2
    echo "兩個數位分別為 $n1 和 $n2 "
    return $(($n1+$n2))
}
sum
echo "兩個數位的和為: $? "  # 獲取函數返回值

執行上面的shell,觀察輸出效果

案例3:有參函數

在Shell中,呼叫函數時可以向其傳遞引數。在函數體內部,通過 $n 的形式來獲取引數的值,例如,$1 表示第一個引數,$2 表示第二個引數...

其他引數介紹

引數處理說明
$#傳遞到指令碼或函數的引數個數
$*以一個單字串顯示所有向指令碼傳遞的引數
$$指令碼執行的當前程序ID號
$!後臺執行的最後一個程序的ID號
$@與$*相同,但是使用時加引號,並在引號中返回每個引數。
$?顯示最後命令的退出狀態。0表示沒有錯誤,其他任何值表明有錯誤。

案例介紹

使用上面的引數編寫一個輸出使用者輸入引數的範例

#!/bin/bash
funParam(){
    echo "第一個引數為 $1 !"
    echo "第二個引數為 $2 !"
    echo "第十個引數為 $10 !"
    echo "第十個引數為 ${10} !"
    echo "第十一個引數為 ${11} !"
    echo "引數總數有 $# 個!"
    echo "作為一個字串輸出所有引數 $* !"
}
 
funParam 1 2 3 4 5 6 7 8 9 10 11 12 15

呼叫上面的指令碼觀察效果

補充:Shell程式與函數的區別

函數和shell程式比較相似,區別在於:

  • Shell 程式(內建命令和外部指令碼檔案), 外部指令碼檔案是在子Shell中執行, 會開啟獨立的程序執行;
  • Shell函數在當前Shell的程序中執行;

linux shell程式設計常用案例介紹

以下結合前面關於shell程式設計技術點的介紹,列舉常用的一些可以使用shell程式設計來處理的場景

1、紀錄檔(資料)備份

比如生產環境下,為了保留每天的核心紀錄檔,可以使用定時任務,排程某個shell指令碼,在指令碼中編寫程式用於備份紀錄檔資料

參考範例

#!/bin/bash  
tar  -zcvf  log-`date +%Y-%m-%d`.tar.gz log-`date +%Y-%m-%d` /var/log   

2、監控記憶體和磁碟容量,小於給定值時報警

當生產伺服器的記憶體和磁碟容量不足時,可以通過編寫shell進行監控報警

參考範例

#!/bin/bash  
# 提取根分割區剩餘空間  
disk_size=$(df / | awk '///{print $4}')  
  
# 提取記憶體剩餘空間  
mem_size=$(free | awk '/Mem/{print $4}')  
while :  
do  
# 注意記憶體和磁碟提取的空間大小都是以 Kb 為單位  
if  [  $disk_size -le 512000 -a $mem_size -le 1024000  ]  
then  
    mail  ‐s  "Warning"  root  <<EOF  
  Insufficient resources,資源不足  
EOF  
fi  
done  

3、檢視有多少遠端 IP 連線本機

參考範例

#!/bin/bash  
  
# 檢視多少遠端 IP 連線本機(不管是通過 ssh 還是 web 還是 ftp 都統計)   
# 使用 netstat ‐atn 可以檢視本機所有連線的狀態,‐a 檢視所有,  
# -t僅顯示 tcp 連線的資訊,‐n 數位格式顯示  
# Local Address(第四列是本機的 IP 和埠資訊)  
# Foreign Address(第五列是遠端主機的 IP 和埠資訊)  
# 使用 awk 命令僅顯示第 5 列資料,再顯示第 1 列 IP 地址的資訊  
# sort 可以按數位大小排序,最後使用 uniq 將多餘重複的刪除,並統計重複的次數  
 
netstat -atn  |  awk  '{print $5}'  | awk  '{print $1}' | sort -nr  |  uniq -c  

4、編寫nginx啟動指令碼

在實際的運維中,很多中介軟體服務,為了方便管理各個中介軟體服務,可以考慮將其做成各類啟動指令碼,統一維護,下面以nginx為例說明(其他的,比如redis,zk等可以類似的參考進行編寫);

#!/bin/bash  
  
# 指令碼編寫完成後,放置在/etc/init.d/目錄下,就可以被 Linux 系統自動識別到該指令碼  
# 如果指令碼名為/etc/init.d/nginx,則 service nginx start 就可以啟動該服務  
# service nginx stop 就可以關閉服務  
# service nginx restart 可以重啟服務  
# service nginx status 可以檢視服務狀態  
program=/usr/local/nginx/sbin/nginx  
pid=/usr/local/nginx/logs/nginx.pid  
start(){  
if [ -f $pid ];then  
  echo  "nginx 服務已經處於開啟狀態"  
else  
  $program  
fi  
stop(){  
if [ -! -f $pid ];then  
  echo "nginx 服務已經關閉"  
else  
  $program -s stop  
  echo "關閉服務 ok"  
fi  
}  
status(){  
if [ -f $pid ];then  
  echo "服務正在執行..."  
else  
  echo "服務已經關閉"  
fi  
}  
  
case $1 in  
start)  
  start;;  
stop)  
  stop;;  
restart)  
  stop  
  sleep 1  
  start;;  
status)  
  status;;  
*)  
  echo  "你輸入的語法格式錯誤"  
esac  

到此這篇關於linux shell 程式設計之函數使用的文章就介紹到這了,更多相關linux shell 函數使用內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com