linux脚本编程有参函数,shell脚本编程进阶:函数
一、函數介紹
函數function是由若干條shell命令組成的語句塊,實現代碼重用和模塊化編程;
它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell程序的一部分;
函數和shell程序比較相似,區別在于:
(1)Shell程序在子Shell中運行;
(2)Shell函數在當前Shell中運行;因此在當前Shell中,函數可以對shell中變量進行修改;
例如:
腳本1:clean.sh:rm -rf /app/x/*
腳本2:f1.sh:
#!/bin/bash
echo f1.sh
/app/bin/clean.sh(bash調用)
二、定義函數
定義函數=定義別名;
建議不要用與系統cmd相同的函數名;
企業規范函數命名:f_name 或者 func_name;
declear -f f_name 查看某個函數
declear -f 查看所有函數
declear -x 查看所有環境變量
unset f_name 取消(刪除)函數
函數(兩部分組成):函數名和函數體;
help function
語法一:
function f_name {
...函數體...
}
語法二:
function f_name(){
...函數體...
}
語法三:(建議)
f_name(){
...函數體...
}
注意:
function f_name(){ cmd; }
不換行——必須加 ;和 “空格”(中括號里);
例如:
function clean () { echo clean1;echo clean2; }
clean
unset clean
三、函數的定義和使用
1.函數——聲明、定義;函數生效——調用;(先定義,后調用)
2.函數只有被調用才會執行;
3.調用方法:給定函數名;
4.函數名出現的地方,會被自動替換為函數代碼;
5.函數的生命周期:被調用時創建,返回時終止;
(1)交互式環境下定義函數;(類似cat)
f_name {
>...
>...
>}
(2)將函數放在腳本文件中作為它的一部分;
在腳本前面先定義函數;然后在調用函數;只適用于自己使用;
#!/bin/bash
f_name {
echo f_name
}
f_name
(3)放在只包含函數的單獨文件中;(可以被其他文件調用)
系統定義的函數都放在這個文件:cat /etc/init.d/functions;
grep '^.*().*' /etc/init.d/functions|wc -l 統計函數庫中函數個數
自己可以定義:vim functions (定義函數的文件,可以不寫shebang機制)
f_name1 {
echo f_name
}
f_name2 {
echo f_name
}
例如:testfuc.sh
#!/bin/bash
. /app/bin/functions (調用函數庫)
echo cmd1 (腳本自己的程序)
f_name1 (調用的函數)
f_name2 (調用的函數)
四、函數返回值(兩種)
1.函數的執行結果返回值
(1)使用echo等命令進行輸出;
(2)函數體中調用命令的輸出結果;
2.函數的退出狀態碼
(1)默認取決于函數中執行的最后一條命令的退出狀態碼;
(2)自定義退出狀態碼,其格式為:
return 從函數中返回,用最后狀態命令決定返回值
return 0 無錯誤返回
return 1-255 有錯誤返回
例1
vim functions
func1 {
echo 100
}
func2 {
echo func2-cmd1
return(100或者exit)
echo func2-cmd2
}
. functions 使系統里有緩存(如果更改functions文件,需要重新使其重新生效,就執行此操作)
func1:100 使系統里有緩存
let i=`func1`+200 `func1`可被其他命令調用(即:當做別名使用)
echo $i:300
func2:(1)return:退出函數;(2)exit:退出腳本;
例2
vim testfunc.sh
. /app/bin/functions(例1中的functions庫)
func2 (例1中的func2)
echo continue
testfunc.sh(運行)
(1)return:退出函數;func2-cmd1 continue
(2)exit:退出腳本;func2-cmd1
例3
vim testfunc.sh
. /app/bin/functions(例1中的functions庫)
func2 (例1中的func2)
echo $? return 顯示:0(真);return 100 顯示:100(假);
echo continue
五、使用函數文件
1.可以將經常使用的函數存入函數文件,然后將函數文件載入shell;
2.文件名可任意選取,但最好與相關任務有某種聯系;例如:functions.main;
3.一旦函數文件載入shell,就可以在命令行或腳本中調用函數;
set 查看所有定義的函數,其輸出列表包括已經載入shell的所有函數;
4.若要改動函數,首先用unset命令從shell中刪除函數;改動完畢后,再重新載入此文件;
國際象棋(思路)
red(){ echo -e '\033[41m \033[0m'; };red
red;red;red;red
yellow(){ echo -e '\033[43m \033[0m'; };yellow
yellow;yellow;yellow;yellow
red;red;red;red;yellow;yellow;yellow;yellow
六、函數參數
cat /etc/init.d/sshd
腳本調用參數
(空格)/etc/init.d/sshd status
(空格)/etc/init.d/sshd restart
1.函數可以接受參數
(1)傳遞參數給函數
調用函數時,在函數名后面以空白分隔給定參數列表即可;
例如:“testfunc arg1 arg2 ...”;
(2)在函數體中,
使用 $1, $2, ...調用這些參數;還可以使用 $@, $*, $# 等特殊變量;
例
(1)vim functions
func {
echo 1st is $1
echo 2st is $2
echo all args are $*
echo the arg numbers is $#
echo funcname is $0
}
max {
[ $1 -gt $2 ] && echo max is $1 || echo max is $2
}
(2)testfunc1.sh
. /app/bin/functions
func a b c
echo continue
(3)testfunc2.sh
. /app/bin/functions
max 10 20
echo continue
(4). functions 更改functions文件,需要重新使其重新生效
2.函數變量
變量作用域
(1)環境變量:當前shell和子shell有效;
(2)本地變量:只在當前shell進程有效,為執行腳本會啟動專用子shell進程;作用范圍是當前shell腳本程序文件,包括腳本中的函數;
(3)局部變量:函數的生命周期;函數結束時變量被自動銷毀;
(4)注意:如果函數中有局部變量,如果其名稱同本地變量,使用局部變量
(5)在函數中定義局部變量的方法
local NAME=VALUE
使用腳本中定義的變量(最好加上括號)
(1)vim functions
func () {
(var=fuc)函數是否定義變量
echo $var
echo func-cmd1
return 100
echo func-cmd2
}
(2)vim testfunc.sh
. /app/bin/functions
var=testfunc
func
echo continue
(3). functions 更改functions文件,需要重新使其重新生效
(4)testfunc.sh
函數未定義變量:testfunc func-cmd1 continue
函數定義變量:func func-cmd1 continue
變量名相同時,函數里的變量可以更改腳本中的變量;所以盡量避免變量名稱相同(防止混亂);
local NAME=VALUE 此變量只在函數中有效
為了區分,可以統一變量名:local local_NAME=VALUE
步驟1:vim functions
func () {
local var=fuc
echo $var
echo func-cmd1
return 100
echo func-cmd2
}
步驟2:vim testfunc.sh
. /app/bin/functions
var=testfunc
echo var=$var
func
echo var=$var
echo continue
步驟3:. functions 更改functions文件,需要重新使其重新生效
步驟4:bash testfunc.sh
七、函數遞歸
函數遞歸:函數直接或間接調用自身;注意遞歸層數;
n!=1×2×3×...×n
n!=(n-1)!×n
n!=(n-2)!×(n-1)×n
vim fact.sh
#!/bin/bash
fact () {
if [ $1 -eq 0 -o $1 -eq 1 ]; then
echo 1
else
echo $[$1*$(fact $[$1-1])]
fi
}
fact $1(調用自己+參數)
執行操作
fact.sh 10
fact.sh -1 死循環;直至資源耗盡;
killall fact.sh
pstree -p 保留原來狀態(進程),循環下一個狀態(進程);
ps auxf|less
linux遞歸函數調用,嵌套深度無限制;編寫腳本時,要注意合理利用函數調用;
Paste_Image.png
fork炸彈
1.fork炸彈
一種惡意程序,它的內部是一個不斷在fork進程的無限循環,實質是一個簡單的遞歸程序;
由于程序是遞歸的,如果沒有任何限制,這會導致這個簡單的程序迅速耗盡系統里面的所有資源;
2.函數實現
:() { :|:& };:
bomb() { bomb | bomb & }; bomb
3.腳本實現
cat bomb.sh
#!/bin/bash
./$0|./$0&
八、匿名函數和環境函數
匿名函數:{ cmd1;cmd2 }
環境函數
(1)定義函數;
(2)declare -fx 或 export -f 聲明環境函數;
(3)調用;
讓子進程繼承父進程的函數;
Paste_Image.png
總結
以上是生活随笔為你收集整理的linux脚本编程有参函数,shell脚本编程进阶:函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++之构造函数和析构函数强化
- 下一篇: 定制化你的ReactNative底部导航