函數:
把一段獨立功能的代碼當作一個整體,并命名一個名字;命名的代碼段,此即為函數
由若干條shell命令組成的語句塊,實現代碼重用和模式化編程
函數的作用:
在某些場景下,我們可以將獨立功能的一段代碼定義為一個函數,用到此功能時,直接調用函數即可,而不必重復編寫代碼,節省一定的代碼量
注意:定義函數的代碼段不會自動執行,在調用時執行;所謂調用函數,在代碼中給定函數名即可;
函數名出線的任何位置,在代碼執行時,都會被自動替換為函數代碼
語法格式:
語法一:
function f_name() {
函數代碼
…
}
語法二:
f_name() {
函數代碼
…
}
函數的定義:
在交互式環境下定義函數,定義完成后,直接調用即可
把函數定義在腳本中,當中腳本的一部分
存放在特定的函數文件當中,用到時直接調用函數文件
函數的生命周期:每次被調用時創建,返回時終止
函數的退出狀態碼:
其狀態返回結果為函數體中運行的最后一條命令的狀態結果
自定義狀態返回值,需要使用:return
return [0-255]
0:成功
1-255:失敗
函數返回值:
函數的執行結果返回值:
(1) 使用echo或printf命令進行輸出
(2)函數體中調用的命令執行結果
函數的退出狀態碼:
(1)默認取決于函數體中執行的最后一條命令的退出狀態碼
(2)自定義:return
函數可以接受參數:
在函數體當中,可以使用$1,$2,…引用傳遞給函數的參數;還可以在函數中使用$*或$@引用所有參數,$#引用傳遞參數的個數
在調用函數時,在函數名后面以空白符分隔給定參數列表即可,例如,func arg1 arg2 arg3…
使用函數文件:
可以將經常使用的函數存放在一個文件當中,然后將函數文件載入shell程序執行,一旦函數載入shell,就可以在命令行或腳本中調用函數
可使用set命令查看當前shell所載入的所有函數
使用unset命令可刪除所指定的函數
載入函數文件:
. filename或source filename
變量作用域:
環境變量:生效范圍為當前shell以及子shell進程
本地變量:生效范圍為當前shell進程,隨著shell進程結束而結束
局部變量:生效范圍為腳本中某一代碼片段,隨著函數的結束而結束
建議在函數當中使用局部變量,因為函數是在當前shell進程中執行的,函數中所定義的變量有可能會和腳本中的變量產生沖突
因此把函數中變量定義為局部變量,只在函數內部中生效
局部變量定義方法;
local NAME="value"
示例:
1.編寫服務腳本/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為當前腳本名
[root@CentOS7 ~]# cat service.sh #!/bin/bash # NAME=$(basename $0) SCRIPTS="/var/lock/subsys/$NAME" function start() { if [ ! -e $SCRIPTS ];then touch $SCRIPTS sleep 1 echo "start service $NAME finished." else echo "$NAME service is running..." fi } function stop() { if [ -e $SCRIPTS ];then rm -f $SCRIPTS sleep 1 echo "stop service $NAME finished." else echo "service $NAME is not running..." fi } function restart() { if [ -e $SCRIPTS ];then rm -f $SCRIPTS touch $SCRIPTS sleep 1 echo "restart service $NAME finished." else touch $SCRIPTS sleep 1 echo "start service $NAME finished." fi } function status() { if [ -e $SCRIPTS ];then echo "service $NAME is running..." else echo "service $NAME is not running..." fi } function error() { echo "Usage: `basename $0` {start|stop|restart|status}" exit 1 } case $1 in start) start ;; stop) stop ;; restart) restart ;; status) status ;; *) error ;; esac [root@CentOS7 ~]# ./service.sh start #啟動服務器 start service service.sh finished. [root@CentOS7 ~]# ./service.sh stop #停止服務 stop service service.sh finished. [root@CentOS7 ~]# ./service.sh restart #如果服務處于停止狀態,則啟動服務 start service service.sh finished. [root@CentOS7 ~]# ./service.sh restart #如果服務處于啟動狀態,則重啟服務 restart service service.sh finished. [root@CentOS7 ~]# ./service.sh status #當前服務運行狀態為啟動 service service.sh is running... [root@CentOS7 ~]# ./service.sh stop #服務運行狀態為未啟用 stop service service.sh finished. [root@CentOS7 ~]# ./service.sh status service service.sh is not running... [root@CentOS7 ~]#
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退出
[root@CentOS7 bin]# cat copycmd.sh #!/bin/bash # function copycmd() { local MKDIR=$DIR$(which --skip-alias $CMD | grep -E -o "^/.*/") [ ! -e $MKDIR ] && mkdir -p $MKDIR cp `which --skip-alias $CMD` $MKDIR [ $? -eq 0 ] && echo "Copy $CMD command file finished." } function copylib() { [ ! -e $DIR$LIB ] && mkdir -p $DIR$LIB local LIBFILE=$(ldd `which --skip-alias $CMD` | grep -E -o "/.*" | sed -r 's@(.*) .*@\1@') cp $LIBFILE $DIR$LIB [ $? -eq 0 ] && echo "Copy $CMD command lib file finished." } DIR="/mnt/sysroot" LIB="/lib64/" read -p "請輸入一個可執行命令:" CMD until [ $CMD == "quit" ] do if ! which --skip-alias $CMD &> /dev/null;then echo "$CMD不是一個可執行命令" read -p "請輸入一個可執行命令:" CMD continue fi copycmd copylib read -p "請輸入一個可執行命令:" CMD done [root@CentOS7 bin]# bash copycmd.sh 請輸入一個可執行命令:ls Copy ls command file finished. Copy ls command lib file finished. 請輸入一個可執行命令:passwd Copy passwd command file finished. Copy passwd command lib file finished. 請輸入一個可執行命令:useradd Copy useradd command file finished. Copy useradd command lib file finished. 請輸入一個可執行命令:quit [root@CentOS7 sysroot]# cd /mnt/sysroot/ [root@CentOS7 sysroot]# cd [root@CentOS7 ~]# cd /mnt/sysroot/ [root@CentOS7 sysroot]# ls lib64 usr [root@CentOS7 sysroot]# ls lib64/ usr/sbin/ usr/bin/ #查看命令文件和庫文件是否復制成功 lib64/: ld-linux-x86-64.so.2 libcap.so.2 libfreebl3.so libpam_misc.so.0 libselinux.so.1 libacl.so.1 libcrypt.so.1 libglib-2.0.so.0 libpam.so.0 libsemanage.so.1 libattr.so.1 libc.so.6 libgmodule-2.0.so.0 libpcre.so.1 libsepol.so.1 libaudit.so.1 libdl.so.2 libgobject-2.0.so.0 libpopt.so.0 libuser.so.1 libbz2.so.1 libffi.so.6 liblzma.so.5 libpthread.so.0 libustr-1.0.so.1 usr/bin/: ls passwd usr/sbin/: useradd [root@CentOS7 sysroot]#
原創文章,作者:zhai796898,如若轉載,請注明出處:http://www.www58058.com/39743