目錄
- 函數(shù)
- 輸入輸出重定向
- 文件包含
1锭环、函數(shù)
函數(shù)可以讓我們將一個(gè)復(fù)雜功能劃分成若干模塊茶鹃,讓程序結(jié)構(gòu)更加清晰,代碼重復(fù)利用率更高四苇。像其他編程語(yǔ)言一樣,Shell 也支持函數(shù)方咆。Shell 函數(shù)必須先定義后使用月腋。
Shell 函數(shù)的定義格式如下:
function_name () {
list of commands
[ return value ]
}
也可以在函數(shù)名前加上關(guān)鍵字 function
:
function function_name () {
list of commands
[ return value ]
}
函數(shù)返回值,可以顯式增加return
語(yǔ)句瓣赂;如果不加榆骚,會(huì)將最后一條命令運(yùn)行結(jié)果作為返回值。
Shell 函數(shù)返回值只能是整數(shù)煌集,一般用來(lái)表示函數(shù)執(zhí)行成功與否妓肢,0
表示成功,其他值表示失敗苫纤。如果return
其他數(shù)據(jù)碉钠,比如一個(gè)字符串,往往會(huì)得到錯(cuò)誤提示:“numeric argument required”
卷拘。
如果一定要讓函數(shù)返回字符串放钦,那么可以先定義一個(gè)變量,用來(lái)接收函數(shù)的計(jì)算結(jié)果恭金,腳本在需要的時(shí)候訪(fǎng)問(wèn)這個(gè)變量來(lái)獲得函數(shù)返回值。
示例一:無(wú)返回值
hello(){
echo "hello world"
}
hello
輸出:
hello world
調(diào)用函數(shù)只需要給出函數(shù)名褂策,不需要加括號(hào).
示例二:
hello(){
echo "請(qǐng)輸入數(shù)字:"
read num1
echo "請(qǐng)輸入數(shù)字:"
read num2
return $(($num1 + $num2))
#return `expr $nun1 + $num2`
}
hello
result=$?
echo "運(yùn)行結(jié)果:$result"
運(yùn)行結(jié)果:
請(qǐng)輸入數(shù)字:
2
請(qǐng)輸入數(shù)字:
4
運(yùn)行結(jié)果:6
函數(shù)返回值在調(diào)用該函數(shù)后通過(guò) $? 來(lái)獲得.
實(shí)例三:函數(shù)嵌套
print(){
echo "函數(shù)的嵌套"
}
hello(){
print
}
hello
輸出:
函數(shù)的嵌套
像刪除變量一樣横腿,刪除函數(shù)也可以使用 unset
命令,不過(guò)要加上-f
選項(xiàng)斤寂,如下所示
$unset -f function_name
函數(shù)參數(shù)
在Shell
中耿焊,調(diào)用函數(shù)時(shí)可以向其傳遞參數(shù)。在函數(shù)體內(nèi)部遍搞,通過(guò) $n
的形式來(lái)獲取參數(shù)的值罗侯,例如,$1
表示第一個(gè)參數(shù)溪猿,$2
表示第二個(gè)參數(shù)...
示例:
func_parameter(){
echo "參數(shù)1:$1"
echo "參數(shù)4:$4"
echo "參數(shù)9:$9"
echo "參數(shù)10:$10"
echo "參數(shù)12:$12"
}
func_parameter 2 3 4 5 6 7 8 9 10 11 12 13
輸出:
參數(shù)1:2
參數(shù)4:5
參數(shù)9:10
參數(shù)10:20
參數(shù)12:22
可以看到結(jié)果有問(wèn)題钩杰,哪里來(lái)的20、22诊县?
注意讲弄,$10 不能獲取第十個(gè)參數(shù),獲取第十個(gè)參數(shù)需要${10}依痊。當(dāng)n>=10時(shí)避除,需要使用${n}來(lái)獲取參數(shù)
$10被解釋成${1}0,因?yàn)?{1}是2,然后再和0拼接就成了20
$12被解釋成${1}2瓶摆,因?yàn)?{1}是2凉逛,然后再和2拼接就成了21
正確寫(xiě)法:
func_parameter(){
echo "參數(shù)1:$1"
echo "參數(shù)4:$4"
echo "參數(shù)9:$9"
echo "參數(shù)10:${10}"
echo "參數(shù)12:${12}"
}
func_parameter 2 3 4 5 6 7 8 9 10 11 12 13
輸出:
參數(shù)1:2
參數(shù)4:5
參數(shù)9:10
參數(shù)10:11
參數(shù)12:13
另外,還有幾個(gè)特殊變量用來(lái)處理參數(shù)群井,前面已經(jīng)提到:
2状飞、輸入輸出重定向
Unix 命令默認(rèn)從標(biāo)準(zhǔn)輸入設(shè)備(stdin)獲取輸入,將結(jié)果輸出到標(biāo)準(zhǔn)輸出設(shè)備(stdout)顯示蝌借。一般情況下昔瞧,標(biāo)準(zhǔn)輸入設(shè)備就是鍵盤(pán),標(biāo)準(zhǔn)輸出設(shè)備就是終端菩佑,即顯示器自晰。
輸出重定向
命令的輸出不僅可以是顯示器,還可以很容易的轉(zhuǎn)移向到文件稍坯,這被稱(chēng)為輸出重定向.
命令輸出重定向的語(yǔ)法為:
$ command > file
這樣酬荞,輸出到顯示器的內(nèi)容就可以被重定向到文件。
例如瞧哟,下面的命令在顯示器上不會(huì)看到任何輸出:
$ who > users
打開(kāi)生成的users文件混巧,看到輸出內(nèi)容:
chenzhichao console Mar 3 10:15
chenzhichao ttys001 Mar 6 09:48
chenzhichao ttys003 Mar 16 14:59
chenzhichao ttys007 Mar 7 14:33
輸出重定向會(huì)覆蓋文件內(nèi)容,如果不希望文件內(nèi)容被覆蓋,可以使用 >>
追加到文件末尾,
示例:
echo "hello world" >> users
echo "哈哈哈??" >> users
cat users
輸出:
hello world
哈哈哈??
使用 cat 命令查看文件內(nèi)容
輸入重定向
和輸出重定向一樣勤揩,Unix 命令也可以從文件獲取輸入咧党,語(yǔ)法為:
command < file
這樣,本來(lái)需要從鍵盤(pán)獲取輸入的命令會(huì)轉(zhuǎn)移到文件讀取內(nèi)容陨亡。
注意:輸出重定向是大于號(hào)(>)傍衡,輸入重定向是小于號(hào)(<)。
示例:計(jì)算 users 文件中的行數(shù)负蠕,可以使用下面的命令:
wc -l users
輸出2 users
也可以將輸入重定向到 users 文件:
wc -l < users
輸出:2
注意:上面兩個(gè)例子的結(jié)果不同:第一個(gè)例子蛙埂,會(huì)輸出文件名;第二個(gè)不會(huì)遮糖,因?yàn)樗鼉H僅知道從標(biāo)準(zhǔn)輸入讀取內(nèi)容绣的。
重定向深入講解
一般情況下,每個(gè) Unix/Linux 命令運(yùn)行時(shí)都會(huì)打開(kāi)三個(gè)文件:
- 標(biāo)準(zhǔn)輸入文件(stdin):stdin的文件描述符為0欲账,Unix程序默認(rèn)從stdin讀取數(shù)據(jù)屡江。
- 標(biāo)準(zhǔn)輸出文件(stdout):stdout 的文件描述符為1,Unix程序默認(rèn)向stdout輸出數(shù)據(jù)敬惦。
- 標(biāo)準(zhǔn)錯(cuò)誤文件(stderr):stderr的文件描述符為2盼理,Unix程序會(huì)向stderr流中寫(xiě)入錯(cuò)誤信息。
默認(rèn)情況下俄删,command > file
將 stdout
重定向到 file
宏怔,command < file
將stdin
重定向到file
奏路。
示例:users文件內(nèi)容進(jìn)行大小寫(xiě)轉(zhuǎn)換,然后重新輸出到 > users2
tr 'a-z' 'A-Z' < users > users2
示例:用bc命令來(lái)計(jì)算cal.txt輸入中的內(nèi)容
echo 1+2 > cal.txt
bc < cal.txt
示例:用sort命令來(lái)對(duì)輸入文件排序臊诊,排序后重定向到輸出文件
$ cat fruits_in
tomato
strawberry
pear
apple
cherry
$ sort < fruits_in > fruits_out
$ cat fruits_out
apple
cherry
pear
strawberry
tomato
Here Document:
Here Document:是Shell中的一種特殊的重定向方式鸽粉,它的基本的形式如下:
command << delimiter
document
delimiter
它的作用是將兩個(gè)delimiter之間的內(nèi)容(document) 作為輸入傳遞給command. 最主要的用途:用于腳本命令行交互中.
- 開(kāi)始的delimiter前后的空格會(huì)被忽略掉.
- 結(jié)尾的delimiter一定要頂格寫(xiě),前面不能有任何字符抓艳,后面也不能有任何字符触机,包括空格和tab縮進(jìn)
- delimiter可以使任何tag,只要滿(mǎn)足上面兩個(gè)條件
- Here Document可用于命令行中,或腳本里面
示例1:用wc -l命令計(jì)算document的行數(shù)
wc -l << TEXT
line 1
line 2
line 3
line 4
TEXT
輸出4
示例2:用cat命令將here docuemnt讀取出來(lái)
cat << TAG
hello
apple
??
TAG
輸出:
hello
apple
??
3玷或、文件包含
和其他語(yǔ)言一樣儡首,Shell 也可以包含外部腳本。這樣可以很方便的封裝一些公用的代碼作為一個(gè)獨(dú)立的文件偏友。
Shell 文件包含的語(yǔ)法格式如下:
. filename
或
source filename
兩種方式的效果相同蔬胯,簡(jiǎn)單起見(jiàn),一般使用點(diǎn)號(hào)(.)位他,但是注意點(diǎn)號(hào)(.)和文件名中間有一空格
示例:創(chuàng)建腳本test2.sh氛濒,并添加內(nèi)容:
str="this is a string"
再創(chuàng)建test.sh,添加代碼:
#. ./test2.sh
source ./test2.sh
echo $str
輸出:
this is a string