由於Shell編程主要是依賴於Linux,將Linux的命令經過一系列的操作從而完成一個複雜的功能。如果你沒有Linux基礎,沒有Shell的一些基礎知識,建議你先看博主之前寫的文章。
傳送門:
Linux常用的終端命令彙總(超詳細,超全面)收藏這一篇就夠了
Shell學習筆記(1)——Shell的基本原理及Shell編程初體驗
Shell學習筆記(2)——Shell變量及常用的程序語句詳細介紹
小夥伴們一定要看到文章結束啊!文末提供有Shell學習的電子書!
小夥伴們一定要看到文章結束啊!文末提供有Shell學習的電子書!
小夥伴們一定要看到文章結束啊!文末提供有Shell學習的電子書!
Shell函數的調用
使用函數可以節省大量的腳本編寫時間。創建可用和可重用的腳本很有意義,可以使主腳本變短,結構更加清晰。當創建了許多函數後,將之放入函數文件裏,然後其他腳本就可以使用這些函數了。
腳本中調用函數的格式
方式一:
value_name='function_name [arg1 arg2 ...]' #函數的所有標準輸出都傳遞給了主程序的變量
方式二:
function_name [arg1 arg2 ...]
echo $? #得到函數的返回值的狀態
腳本中函數調用示例
grep_user() #定義一個篩選用戶的函數
{
R='grep "$1" /etc/passwed | wc -l'#如果有該用戶,則通過命令置換賦值給R
echo $R #打印出是否有該用戶,如果有該用戶則打印1,沒有打印0
return $R
}
echo -n "input username:" #提示輸入用戶名
read USER
grep_user $USER #調用篩選用戶的函數
# echo "-$?-" #打印出函數的返回值
RET=$?
if [ $RET -eq 1] #如果返回值是1
then
echo "$USER exitst" #提醒存在用戶
else
echo "$USER no_exitst" #提醒不存在用戶
fi
注意:如果定義的函數沒有返回值,那麼會將函數的打印值作爲返回值傳遞給調用該函數的變量。
當我們運行以上程序是會發現有bug,當輸入某些不存在的用戶時,依舊會提示該用戶存在。這是爲什麼呢?
仔細觀察代碼會發現,讀入的變量沒有限制,而這個變量有可能恰巧是存在用戶中的連續字母,從而導致了bug。可能文字有點繞,那麼通過舉一個例子來說明吧!
本來存在一個名字爲linux的用戶,當我們輸入linux的時候,毫無疑問是存在該用戶的,沒有問題。然而當我們輸入lin的時候發現也會提示存在該用戶,這就是原因所在——因爲它和存在的用戶名中的字母重複了。
通過以上分析,發現了問題所在,那麼就快點改bug吧!將定義的grep_user()
函數改成一下內容:
grep_user() #定義一個篩選用戶的函數
{
R='grep "^$1:" /etc/passwed | wc -l'#如果有該用戶,則通過命令置換賦值給R
echo $R #打印出是否有該用戶,如果有該用戶則打印1,沒有打印0
return $R
}
注意變化,是將第三行的命令置換給改了一下,必須要滿足條件:
①以輸入的字母開頭
②以冒號結束
從函數文件中調用函數
前面講述了怎樣在命令行中調用函數,這類函數通常用於系統報表功能。現在再次使用上面的函數,但是這次將之放入函數文件 functions.sh裏。 function.sh文件內容如下:
#!/bin/bash
#functions.sh
#主要腳本的功能
is_it_a_directory()
{
# to ca11: is_it_a_directory directory_name
if[$#-1t1];then
echo "is_it_a_directory: I need a directory name to check"
return 1
fi
# is it a directory ?
DIRECTORY_NAME=$1
if[ ! -d $DIRECTORY_ NAME ] ; then
return 1
else
return 0
fi
}
error_ _msg()
{
echo -e "\007"
echo $@
echo -e "\007"
return 0
}
現在編寫腳本就可以調用function.sh中的函數了。注意函數文件在腳本中以下述命令格式定位:. \<path to file>
使用這種方法不會創建另一個shell,所有函數均在當前 shell下執行。
新建一個文件夾並命名爲direc_ check
,內容如下:
!/bin/bash
echo -n " enter destination directory :"
read DIREC
if is_it_a_directory $DIREC
then :
else
error_msg " $DIREC does not exist...creating it now"
mkdir $DIREC > /dev/nu11 2>&1#將標準輸出,錯誤輸出都重定向至/dev/null,也就是全部丟棄
if[$?!=0]
then
error_msg "Cou1d not create directory:: check it out!"
exit 1
else :
fi
echo "extracting files..."
以上代碼中用到了輸出重定向的知識,博主這裏就不詳細介紹了,因爲已經有其它的博主寫的很詳細了——文章傳送門:Shell中的>/dev/null 2>&1 與 2>&1 >/dev/null 與&>/dev/null 的區別
函數變量作用域
- 全局作用域:在腳本的其它任何地方都能夠訪問到該變量
- 局部作用域:只能聲明變量的作用域內訪問
- 聲明局部變量的格式:
Local variable_name =value
示例
grep_user()
{
A=100
B=200
}
grep_user
echo "end:$A-$B"
很過小夥伴可能會想到C語言中,這樣應該會報錯啊!實際上是不會報錯的,因爲在上面函數內定義的A變量和B變量依舊是全局變量。定義局部變量必須在變量名前加上local
grep_user()
{
local A=100
B=200
}
grep_user
echo "end:$A-$B"
可以看到打印結果沒有A
文末送福利
Shell學習電子書
提取碼:yvgg
不積小流無以成江河,不積跬步無以至千里。而我想要成爲萬里羊,就必須堅持學習來獲取更多知識,
用知識來改變命運,用博客見證成長,用行動證明我在努力
。
如果我的博客對你有幫助、如果你喜歡我的博客內容,請“點贊” “評論” “收藏”
一鍵三連哦!聽說點讚的人運氣不會太差,每一天都會元氣滿滿呦!如果實在要白嫖的話,那祝你開心每一天,歡迎常來我博客看看。