來源: Linux命令行與shell腳本編程大全
博客地址蓝仲,推薦電腦點
內(nèi)容
- 基本的腳本函數(shù)
- 返回值
- 在函數(shù)中使用變量
- 數(shù)組變量和函數(shù)
- 函數(shù)遞歸
- 創(chuàng)建庫
- 在命令行上使用函數(shù)
我們可以將shell腳本代碼放進函數(shù)中封裝起來橡卤,這樣就能在腳本中的任何地方多次使用它了。
下面我們來逐步了解如何創(chuàng)建自己的shell腳本函數(shù)并在應(yīng)用中使用它們嫩实。
基本的腳本函數(shù)
函數(shù)是一個腳本代碼塊棒假,我們可以為其命名并在代碼中任何位置重用麸锉。要在腳本中使用該代碼塊,只要使用所起的函數(shù)名就行了扎即。
創(chuàng)建函數(shù)
有兩種格式可以創(chuàng)建函數(shù)。第一種格式是使用關(guān)鍵字function
况凉,后跟分配給該代碼塊的函數(shù)名谚鄙。
funtion name{
commands
}
name
屬性定義了賦予函數(shù)的唯一名稱,commands
是構(gòu)成函數(shù)的一條或多條bash shell命令刁绒。
第二種格式更接近其他編程語言中定義函數(shù)的方式:
name() {
commands
}
使用函數(shù)
要使用函數(shù)闷营,只需要像其他shell命令一樣,在行中指定函數(shù)名就行了知市。
wsx@wsx:~/tmp$ cat test1
#!/bin/bash
# using a function in a script
function func1 {
echo "This is an example of a function"
}
count=1
while [ $count -le 5 ]
do
func1
count=$[ $count + 1 ]
done
echo "This is the end of the loop"
func1
echo "Now, this is the end of the script"
wsx@wsx:~/tmp$ ./test1
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is an example of a function
This is the end of the loop
This is an example of a function
Now, this is the end of the script
注意傻盟,定義函數(shù)名func1
的后面一定要跟{
有空格隔開,不然會報錯嫂丙。函數(shù)要先定義再使用娘赴,接觸過編程的想必不陌生吧。
返回值
bash shell會把函數(shù)當(dāng)做一個小型腳本跟啤,運行結(jié)束時會返回一個退出狀態(tài)碼诽表,有3種不同的方法來為函數(shù)生成退出狀態(tài)碼。
默認(rèn)退出狀態(tài)碼
默認(rèn)函數(shù)的退出狀態(tài)碼是函數(shù)中最后一條命令返回的退出狀態(tài)碼隅肥。我們可以使用標(biāo)準(zhǔn)變量$?
在函數(shù)執(zhí)行結(jié)束后確定函數(shù)的狀態(tài)碼关顷。
wsx@wsx:~/tmp$ cat test2
#!/bin/bash
# testing the exit status of a function
func1() {
echo "trying to display a non-existent file"
ls -l badfile
}
echo "testing the function"
func1
echo "The exit status is: $?"
wsx@wsx:~/tmp$ ./test2
testing the function
trying to display a non-existent file
ls: 無法訪問'badfile': 沒有那個文件或目錄
The exit status is: 2
函數(shù)的退出狀態(tài)碼是2,說明函數(shù)的最后一條命令沒有成功運行武福。但你無法知道函數(shù)中其他命令中是否成功運行议双,我們來看看下面一個例子。
wsx@wsx:~/tmp$ cat test3
#!/bin/bash
# testing the exit status of a function
func1(){
ls -l badfile
echo "This was a test of a bad command"
}
echo "testing the function:"
func1
echo "The exit status is: $?"
wsx@wsx:~/tmp$ ./test3
testing the function:
ls: 無法訪問'badfile': 沒有那個文件或目錄
This was a test of a bad command
The exit status is: 0
這次函數(shù)的退出狀態(tài)碼是0捉片,盡管其中有一條命令沒有正常運行平痰。可見使用函數(shù)的默認(rèn)退出狀態(tài)碼是很危險的伍纫,幸運的是宗雇,我們有幾種辦法解決它。
使用return命令
return
命令允許指定一個整數(shù)值來定義函數(shù)的退出狀態(tài)碼莹规,從而提供了一種簡單的途徑來編碼設(shè)定函數(shù)退出狀態(tài)碼赔蒲。
wsx@wsx:~/tmp$ cat test4
#!/bin/bash
# using the return command in a function
function db1 {
read -p "Enter a value: " value
echo "doubling the value"
return $[ $value * 2 ]
}
db1
echo "The new value is $?"
wsx@wsx:~/tmp$ ./test4
Enter a value: 4
doubling the value
The new value is 8
當(dāng)使用這種方法時要小心,記住下面兩條技巧來避免問題:
- 函數(shù)一結(jié)束就取返回值
- 退出狀態(tài)碼必須是0~255
如果在用$?
變量提取函數(shù)的返回值之前使用了其他命令,函數(shù)的返回值就會丟失舞虱。任何大于255的整數(shù)值都會產(chǎn)生一個錯誤值欢际。
wsx@wsx:~/tmp$ ./test4
Enter a value: 200
doubling the value
The new value is 144
使用函數(shù)輸出
如同可以將命令的輸出保存到shell變量一樣,我們也可以對函數(shù)的輸出采用同樣的處理辦法矾兜。
result=`db1`
這個命令會將db1
函數(shù)的輸出賦值給$result
變量损趋。下面是腳本的一個實例:
wsx@wsx:~/tmp$ cat test4b
#!/bin/bash
# using the echo to return a value
function db1 {
read -p "Enter a value: " value
echo $[ $value * 2 ]
}
result=$(db1)
echo "The new value is $result"
wsx@wsx:~/tmp$ ./test4b
Enter a value: 200
The new value is 400
函數(shù)會用echo
語句來顯示計算的結(jié)果,該腳本會查看db1
函數(shù)的輸出椅寺,而不是查看退出狀態(tài)碼浑槽。
通過這種技術(shù),我們還可以返回浮點值和字符串值返帕,這使它成為一種獲取函數(shù)返回值的強大方法桐玻。
在函數(shù)中使用變量
在函數(shù)中使用變量時,我們需要注意它們的定義方式以及處理方法荆萤。這是shell腳本常見錯誤的根源畸冲。
向函數(shù)傳遞參數(shù)
函數(shù)可以使用標(biāo)準(zhǔn)的參數(shù)環(huán)境變量來表示命令行上傳給函數(shù)的參數(shù)。例如观腊,函數(shù)名會在$0
變量中定義邑闲,函數(shù)命令行上的任何參數(shù)都會通過$1
、$2
定義梧油。也可以用特殊變量$#
來判斷給函數(shù)的參數(shù)數(shù)目苫耸。
指定函數(shù)時,必須將參數(shù)和函數(shù)放在同一行:
func1 $value1 10
然后函數(shù)可以用參數(shù)環(huán)境變量來獲得參數(shù)值儡陨。下面是一個例子:
wsx@wsx:~/tmp$ cat test5
#!/bin/bash
# passing parameters to a function
function addem {
if [ $# -eq 0 ] || [ $# -gt 2 ]
then
echo -1
elif [ $# -eq 1 ]
then
echo $[ $1 + $1 ]
else
echo $[ $1 + $2 ]
fi
}
echo -n "Adding 10 and 15: "
value=$(addem 10 15)
echo $value
echo -n "Let's try adding just one number: "
value=$(addem 10)
echo $value
echo -n "Now trying adding no numbers: "
value=$(addem)
echo $value
echo -n "Finally, try add three numbers: "
value=$(addem 10 15 20)
echo $value
wsx@wsx:~/tmp$ ./test5
Adding 10 and 15: 25
Let's try adding just one number: 20
Now trying adding no numbers: -1
Finally, try add three numbers: -1
addem
函數(shù)首先會檢查腳本傳給它的參數(shù)數(shù)目褪子。如果沒有任何參數(shù),或者參數(shù)多于兩個骗村,addem
會返回-1
嫌褪。如果只有一個參數(shù),addem
會將參數(shù)與自身相加胚股。如果有兩個參數(shù)笼痛,addem
會將它們相加。
由于函數(shù)使用特殊參數(shù)環(huán)境變量作為自己的參數(shù)值琅拌,因此它無法直接獲取腳本在命令行中的參數(shù)值缨伊。下面是個失敗的例子:
wsx@wsx:~/tmp$ cat badtest1
#!/bin/bash
# trying to access script parameters inside a function
function badfunc1 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(badfunc1)
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
wsx@wsx:~/tmp$ ./badtest1 10 15
./badtest1: 行 5: * : 語法錯誤: 需要操作數(shù) (錯誤符號是 "* ")
The result is
盡管函數(shù)也使用了$1
與$2
變量,但它們與主腳本中的變量不同进宝,要使用它們必須在調(diào)用函數(shù)時手動傳入刻坊。
wsx@wsx:~/tmp$ cat test6
#!/bin/bash
# trying to access script parameters inside a function
function func1 {
echo $[ $1 * $2 ]
}
if [ $# -eq 2 ]
then
value=$(func1 $1 $2)
echo "The result is $value"
else
echo "Usage: badtest1 a b"
fi
wsx@wsx:~/tmp$ ./test6
Usage: badtest1 a b
wsx@wsx:~/tmp$ ./test6 10 15
The result is 150
在函數(shù)中處理變量
作用域是變量可見的區(qū)域。對腳本的其他部分而言党晋,函數(shù)定義的變量是隱藏的谭胚。這些概念其實是編程語言中通用的徐块,想必學(xué)過一些其他編程的朋友早已有所理解了。
函數(shù)使用兩種類型的變量:
- 全局變量
- 局部變量
全局變量
全局變量是在shell腳本中任何地方都有效的變量灾而,如果你在函數(shù)內(nèi)定義了一個全局變量胡控,也可以在腳本的主體部分讀取它的值。
默認(rèn)情況下绰疤,我們在腳本中定義的任何變量都是全局變量铜犬。
wsx@wsx:~/tmp$ cat test7
#!/bin/bash
# using a global variable to pass a value
function db1 {
value=$[ $value * 2 ]
}
read -p "Enter a value: " value
db1
echo "The new value is: $value"
wsx@wsx:~/tmp$ ./test7
Enter a value: 10
The new value is: 20
無論變量在函數(shù)內(nèi)外定義舞终,在腳本中引用該變量都有效轻庆。這樣其實非常危險,尤其是如果你想在不同的shell腳本中使用函數(shù)的話敛劝。它要求你清清楚楚地知道函數(shù)中具體使用了哪些變量余爆,包括那些用來計算非返回值的變量。下面是一個如何搞砸的例子:
wsx@wsx:~/tmp$ cat badtest2
#!/bin/bash
# demonstrating a bad use of variable
function func1 {
temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
wsx@wsx:~/tmp$ ./badtest2
The result is 22
temp is larger
由于函數(shù)中用到了$temp
變量夸盟,它的值在腳本中使用時受到了影響蛾方,產(chǎn)生了意想不到的后果。后面我們會學(xué)習(xí)如何處理這樣的問題上陕。
局部變量
無需在函數(shù)中使用全局變量桩砰,函數(shù)內(nèi)部使用的任何變量都可以被聲明成局部變量。我們只需要在變量聲明前加上local關(guān)鍵字就可以了释簿。
local temp
也可以在變量賦值時使用local關(guān)鍵字:
local temp=$[ $value + 5 ]
local
關(guān)鍵字保證了變量只局限于該函數(shù)中亚隅。我們再回看剛才的例子:
wsx@wsx:~/tmp$ cat test8
#!/bin/bash
# demonstrating the local keyword
function func1 {
local temp=$[ $value + 5 ]
result=$[ $temp * 2 ]
}
temp=4
value=6
func1
echo "The result is $result"
if [ $temp -gt $value ]
then
echo "temp is larger"
else
echo "temp is smaller"
fi
wsx@wsx:~/tmp$ ./test8
The result is 22
temp is smaller
數(shù)組變量和函數(shù)
在函數(shù)中使用數(shù)組變量值有點麻煩,還需要一些特殊考慮庶溶。下面我們使用一種方法來解決問題煮纵。
向函數(shù)傳數(shù)組參數(shù)
這個方法有點不好理解,將數(shù)組變量當(dāng)做單個參數(shù)傳遞的話不起作用偏螺,下面我們看一個bad例子:
wsx@wsx:~/tmp$ cat badtest3
#!/bin/bash
# trying to pass an array variable
function testit {
echo "The parameters are: $@"
thisarray=$1
echo "The received array is ${thisarray[*]}"
}
myarray=(1 2 3 4 5)
echo "The original array is: ${myarray[*]}"
testit $myarray
wsx@wsx:~/tmp$ ./badtest3
The original array is: 1 2 3 4 5
The parameters are: 1
The received array is 1
可以看到行疏,當(dāng)我們將數(shù)組變量當(dāng)做函數(shù)參數(shù)傳遞時,函數(shù)只會取數(shù)組變量的第一個值套像。
針對這個問題酿联,我們的一個解決方案是將數(shù)組變量全部拆分為單個值,然后作為參數(shù)傳入函數(shù)夺巩,在函數(shù)內(nèi)部又重新對這些值進行組裝货葬。
wsx@wsx:~/tmp$ cat test9
#!/bin/bash
# array variable to function test
function testit {
local newarray
newarray=(`echo "$@"`)
echo "The new array value is: ${newarray[*]}"
}
myarray=(1 2 3 4 5)
echo ${myarray[*]}
testit ${myarray[*]}
wsx@wsx:~/tmp$ ./test9
1 2 3 4 5
The new array value is: 1 2 3 4 5
從函數(shù)中返回數(shù)組
采用與上面類似的方法,函數(shù)用echo
語句來按正確順序輸出單個數(shù)組值劲够,然后腳本再將它們重新放進一個新的數(shù)組變量中震桶。
wsx@wsx:~/tmp$ cat test10
#!/bin/bash
# returning an array value
function arraydblr {
local origarray
local newarray
local elements
local i
origarray=($(echo "$@"))
newarray=($(echo "$@"))
elements=$[ $# - 1 ]
for (( i = 0; i <= $elements; i++ ))
{
newarray[$i]=$[ ${origarray[$i]} * 2]
}
echo ${newarray[*]}
}
myarray=(1 2 3 4 5)
echo "The orignal array is ${myarray[*]}"
arg1=$(echo ${myarray[*]})
result=($(arraydblr $arg1))
echo "The new array is: ${result[*]}"
wsx@wsx:~/tmp$ ./test10
The orignal array is 1 2 3 4 5
The new array is: 2 4 6 8 10
該腳本用$arg1
變量將數(shù)組值傳給arraydblr
函數(shù)。該函數(shù)將數(shù)組重組到新的數(shù)組變量中征绎,生成輸出數(shù)組變量的一個副本蹲姐,然后對數(shù)據(jù)元素進行遍歷磨取,將每個元素值翻倍,并將結(jié)果存入函數(shù)中該數(shù)組變量的副本柴墩。
函數(shù)遞歸
局部函數(shù)變量的一個特征是自成體系忙厌。這個特性使得函數(shù)可以遞歸地調(diào)用,也就是函數(shù)可以調(diào)用自己來得到結(jié)果江咳。通常遞歸函數(shù)都有一個最終可以迭代到的基準(zhǔn)值逢净。
遞歸算法的經(jīng)典例子是計算階乘:一個數(shù)的階乘是該數(shù)之前的所有數(shù)乘以該數(shù)的值。
比如5的階乘:
5! = 1 * 2 * 3 * 4 * 5
方程可以簡化為通用形式:
x! = x * (x-1)!
這可以用簡單的遞歸腳本表達為:
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1 ]
local result=`factorial $temp`
echo $[ $result * $1 ]
fi
}
下面用它來進行計算:
wsx@wsx:~/tmp$ cat test11
#!/bin/bash
# using recursion
function factorial {
if [ $1 -eq 1 ]
then
echo 1
else
local temp=$[ $1 - 1]
local result=`factorial $temp`
echo $[ $result * $1 ]
fi
}
read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"
wsx@wsx:~/tmp$ ./test11
Enter value: 5
The factorial of 5 is: 120
創(chuàng)建庫
如果你碰巧要在多個腳本中使用同一段代碼呢歼指?顯然在每個腳本中都定義同樣的函數(shù)太麻煩了爹土,一種解決方法就是創(chuàng)建庫文件,然后在腳本中引用它踩身。
第一步是創(chuàng)建一個包含腳本中所需函數(shù)的公用庫文件胀茵。下面是一個叫做myfuncs的庫文件,定義了3個簡單的函數(shù)挟阻。
wsx@wsx:~/tmp$ cat myfuncs
#!/bin/bash
# my script functions
function addem {
echo $[ $1 + $2 ]
}
function multem {
echo $[ $1 * $2 ]
}
function divem {
if [ $2 -ne 0 ]
then
echo $[ $1 / $2 ]
else
echo -1
fi
}
下一步是在用到這些函數(shù)的腳本文件中包含myfuncs庫文件琼娘。
這里有點復(fù)雜,主要問題出在shell函數(shù)的作用域上附鸽。如果我們嘗試像普通腳本一樣運行庫文件脱拼,函數(shù)不會出現(xiàn)在腳本中。
使用函數(shù)庫的關(guān)鍵在于source
命令坷备。source
命令會在當(dāng)前shell上下文中執(zhí)行命令熄浓,而不是創(chuàng)建一個新的shell。通過source
命令就可以使用庫中的函數(shù)了击你。
source
命令有一個快捷別名玉组,稱為點操作符。要在shell腳本中運行myfuncs庫文件丁侄,只需要使用下面這行:
. ./myfuncs
注意第一個點是點操作符惯雳,而第二個點指向當(dāng)前目錄(相對路徑)。
下面這個例子假定myfuncs庫文件與要使用它的腳本位于同一目錄鸿摇,不然需要使用相對應(yīng)的路徑進行訪問石景。
wsx@wsx:~/tmp$ cat test12
#!/bin/bash
# using functions defined in a library file
. ./myfuncs
value1=10
value2=5
result1=$(addem $value1 $value2)
result2=$(multem $value1 $value2)
result3=$(divem $value1 $value2)
echo "The result of adding them is: $result1"
echo "The result of multiplying them is: $result2"
echo "The result of dividing them is: $result3"
運行:
wsx@wsx:~/tmp$ ./test12
The result of adding them is: 15
The result of multiplying them is: 50
The result of dividing them is: 2
在命令行上使用函數(shù)
有時候有必要在命令行界面的提示符下直接使用這些函數(shù)。這是個灰常不錯的功能拙吉,在shell中定義的函數(shù)可以在整個系統(tǒng)中使用它潮孽,無需擔(dān)心腳本是不是在PATH環(huán)境變量中。
重點在于讓shell能夠識別這些函數(shù)筷黔。以下有幾種方法可以實現(xiàn)往史。
在命令行上創(chuàng)建函數(shù)
shell會解釋用戶輸入的命令,所以可以在命令行上直接定義一個函數(shù)佛舱。
有兩種方法椎例。
一種是采用單行方式定義函數(shù)挨决。
wsx@wsx:~/tmp$ function divem { echo $[ $1 / $2 ]; }
wsx@wsx:~/tmp$ divem 100 5
20
當(dāng)在命令行上定義函數(shù)時,你必須記得在每個命令后面加個分號订歪,這樣shell能識別命令的起始脖祈。
另一種是采用多行方式來定義函數(shù)。在定義時bash shell會使用次提示符來提示輸入更多命令刷晋。這種方法不必在命令末尾加分號盖高,只要按回車鍵就可。
wsx@wsx:~/tmp$ function multem {
> echo $[ $1 * $2 ]
> }
wsx@wsx:~/tmp$ multem 2 5
10
注意:在命令行上創(chuàng)建函數(shù)不要跟內(nèi)建命令重名眼虱,函數(shù)會覆蓋原來的命令喻奥。
在.bashrc文件中定義函數(shù)
在bash shell每次啟動時都會在主目錄下查找.bashrc
文件,不管是交互式shell還是shell中啟動的新shell蒙幻。所以我們可以將函數(shù)寫入該文件映凳,或者在腳本中寫入命令讀取函數(shù)文件胆筒。操作前面都講過邮破,不再贅述,只要把該文件當(dāng)做腳本對待就可以了仆救。理解這一點這部分就會了抒和。
實例
在開源的世界里,共享代碼才是關(guān)鍵彤蔽,而這一點同樣適用于腳本函數(shù)摧莽。我們可以下載大量各式各樣的函數(shù)然后用于自己的應(yīng)用程序。
這一節(jié)介紹如何下載顿痪、安裝和使用GNU shtool shell腳本函數(shù)庫镊辕。shtool庫提供了一些簡單的shell腳本函數(shù),可以用來完成日常的shell功能蚁袭。
下載和安裝
shtool軟件包下載地址:
http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz # China
可以瀏覽器或者命令行下載:
wsx@wsx:~/tmp$ wget http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz
--2017-11-24 00:34:32-- http://mirrors.ustc.edu.cn/gnu/shtool/shtool-2.0.8.tar.gz
正在解析主機 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)... 202.141.176.110, 218.104.71.170, 2001:da8:d800:95::110
正在連接 mirrors.ustc.edu.cn (mirrors.ustc.edu.cn)|202.141.176.110|:80... 已連接征懈。
已發(fā)出 HTTP 請求,正在等待回應(yīng)... 200 OK
長度: 97033 (95K) [application/gzip]
正在保存至: “shtool-2.0.8.tar.gz”
shtool-2.0.8.tar.gz 100%[===================>] 94.76K --.-KB/s 用時 0.1s
2017-11-24 00:34:32 (783 KB/s) - 已保存 “shtool-2.0.8.tar.gz” [97033/97033])
復(fù)制到主目錄揩悄,然后用tar
命令提取文件:
wsx@wsx:~$ tar -zxvf shtool-2.0.8.tar.gz
shtool-2.0.8/AUTHORS
shtool-2.0.8/COPYING
shtool-2.0.8/ChangeLog
shtool-2.0.8/INSTALL
shtool-2.0.8/Makefile.in
shtool-2.0.8/NEWS
shtool-2.0.8/RATIONAL
shtool-2.0.8/README
shtool-2.0.8/THANKS
shtool-2.0.8/VERSION
shtool-2.0.8/configure
shtool-2.0.8/configure.ac
shtool-2.0.8/sh.arx
shtool-2.0.8/sh.common
shtool-2.0.8/sh.echo
shtool-2.0.8/sh.fixperm
shtool-2.0.8/sh.install
shtool-2.0.8/sh.mdate
shtool-2.0.8/sh.mkdir
shtool-2.0.8/sh.mkln
shtool-2.0.8/sh.mkshadow
shtool-2.0.8/sh.move
shtool-2.0.8/sh.path
shtool-2.0.8/sh.platform
shtool-2.0.8/sh.prop
shtool-2.0.8/sh.rotate
shtool-2.0.8/sh.scpp
shtool-2.0.8/sh.slo
shtool-2.0.8/sh.subst
shtool-2.0.8/sh.table
shtool-2.0.8/sh.tarball
shtool-2.0.8/sh.version
shtool-2.0.8/shtool.m4
shtool-2.0.8/shtool.pod
shtool-2.0.8/shtool.spec
shtool-2.0.8/shtoolize.in
shtool-2.0.8/shtoolize.pod
shtool-2.0.8/test.db
shtool-2.0.8/test.sh
接下來可以構(gòu)建shell腳本庫文件了卖哎。
構(gòu)建庫
shtool文件必須針對特定的Linux環(huán)境進行配置。配置工作必須使用標(biāo)準(zhǔn)的configure和make命令:
wsx@wsx:~$ cd shtool-2.0.8/
wsx@wsx:~/shtool-2.0.8$ ./configure
Configuring GNU shtool (Portable Shell Tool), version 2.0.8 (18-Jul-2008)
Copyright (c) 1994-2008 Ralf S. Engelschall <rse@engelschall.com>
checking whether make sets $(MAKE)... yes
checking for perl interpreter... /usr/bin/perl
checking for pod2man conversion tool... /usr/bin/pod2man
configure: creating ./config.status
config.status: creating Makefile
config.status: creating shtoolize
config.status: executing adjustment commands
wsx@wsx:~/shtool-2.0.8$ make
building program shtool
./shtoolize -o shtool all
Use of assignment to $[ is deprecated at ./shtoolize line 60.
Generating shtool...(echo 11808/12742 bytes)...(mdate 3695/4690 bytes)...(table 1818/2753 bytes)...(prop 1109/2038 bytes)...(move 2685/3614 bytes)...(install 4567/5495 bytes)...(mkdir 2904/3821 bytes)...(mkln 4429/5361 bytes)...(mkshadow 3260/4193 bytes)...(fixperm 1471/2403 bytes)...(rotate 13425/14331 bytes)...(tarball 5297/6214 bytes)...(subst 5255/6180 bytes)...(platform 21739/22662 bytes)...(arx 2401/3312 bytes)...(slo 4139/5066 bytes)...(scpp 6295/7206 bytes)...(version 10234/11160 bytes)...(path 4041/4952 bytes)
building manpage shtoolize.1
building manpage shtool.1
building manpage shtool-echo.1
building manpage shtool-mdate.1
shtool-mdate.tmp around line 222: You forgot a '=back' before '=head1'
POD document had syntax errors at /usr/bin/pod2man line 71.
building manpage shtool-table.1
building manpage shtool-prop.1
building manpage shtool-move.1
building manpage shtool-install.1
building manpage shtool-mkdir.1
shtool-mkdir.tmp around line 186: You forgot a '=back' before '=head1'
POD document had syntax errors at /usr/bin/pod2man line 71.
building manpage shtool-mkln.1
building manpage shtool-mkshadow.1
shtool-mkshadow.tmp around line 191: You forgot a '=back' before '=head1'
POD document had syntax errors at /usr/bin/pod2man line 71.
building manpage shtool-fixperm.1
building manpage shtool-rotate.1
building manpage shtool-tarball.1
building manpage shtool-subst.1
building manpage shtool-platform.1
building manpage shtool-arx.1
building manpage shtool-slo.1
building manpage shtool-scpp.1
building manpage shtool-version.1
building manpage shtool-path.1
configure
命令會檢查構(gòu)建shtool庫文件所必需的軟件删性。一旦發(fā)現(xiàn)所需工具亏娜,它會使用工具路徑修改配置文件。
make
命令負(fù)責(zé)構(gòu)建shtool庫文件蹬挺。最終的結(jié)果(shtool)是一個完整的庫軟件包维贺。
我們可以測試下這個庫文件:
wsx@wsx:~/shtool-2.0.8$ make test
Running test suite:
echo..........FAILED
+---Test------------------------------
| test ".`../shtool echo foo bar quux`" = ".foo bar quux" || exit 1
| bytes=`../shtool echo -n foo | wc -c | awk '{ printf("%s", $1); }'` || exit 1
| test ".$bytes" = .3 || exit 1
| bytes=`../shtool echo '\1' | wc -c | awk '{ printf("%s", $1); }'` || exit 1
| test ".$bytes" = .3 || exit 1
| exit 0
+---Trace-----------------------------
| + ../shtool echo foo bar quux
| + test .foo bar quux = .foo bar quux
| + ../shtool echo -n foo
| + wc -c
| + awk { printf("%s", $1); }
| + bytes=3
| + test .3 = .3
| + ../shtool echo \1
| + wc -c
| + awk { printf("%s", $1); }
| + bytes=2
| + test .2 = .3
| + exit 1
+-------------------------------------
mdate.........ok
table.........ok
prop..........ok
move..........ok
install.......ok
mkdir.........ok
mkln..........ok
mkshadow......ok
fixperm.......ok
rotate........ok
tarball.......ok
subst.........ok
platform......ok
arx...........ok
slo...........ok
scpp..........ok
version.......ok
path..........ok
FAILED: passed: 18/19, failed: 1/19
(有一個沒通過~)
如果全部通過測試,就可以將庫安裝到系統(tǒng)中巴帮,這樣所有腳本都能使用這個庫了溯泣。
要完成安裝群发,需要使用make
命令的install
選項。需要使用root權(quán)限发乔。
wsx@wsx:~/shtool-2.0.8$ make install
./shtool mkdir -f -p -m 755 /usr/local
./shtool mkdir -f -p -m 755 /usr/local/bin
./shtool mkdir -f -p -m 755 /usr/local/share/man/man1
mkdir: cannot create directory '/usr/local/share/man/man1': Permission denied
chmod: cannot access '/usr/local/share/man/man1': No such file or directory
Makefile:94: recipe for target 'install' failed
make: *** [install] Error 1
wsx@wsx:~/shtool-2.0.8$ sudo make install
[sudo] wsx 的密碼:
./shtool mkdir -f -p -m 755 /usr/local
./shtool mkdir -f -p -m 755 /usr/local/bin
./shtool mkdir -f -p -m 755 /usr/local/share/man/man1
./shtool mkdir -f -p -m 755 /usr/local/share/aclocal
./shtool mkdir -f -p -m 755 /usr/local/share/shtool
./shtool install -c -m 755 shtool /usr/local/bin/shtool
./shtool install -c -m 755 shtoolize /usr/local/bin/shtoolize
./shtool install -c -m 644 shtoolize.1 /usr/local/share/man/man1/shtoolize.1
./shtool install -c -m 644 shtool.1 /usr/local/share/man/man1/shtool.1
./shtool install -c -m 644 shtool-echo.1 /usr/local/share/man/man1/shtool-echo.1
./shtool install -c -m 644 shtool-mdate.1 /usr/local/share/man/man1/shtool-mdate.1
./shtool install -c -m 644 shtool-table.1 /usr/local/share/man/man1/shtool-table.1
./shtool install -c -m 644 shtool-prop.1 /usr/local/share/man/man1/shtool-prop.1
./shtool install -c -m 644 shtool-move.1 /usr/local/share/man/man1/shtool-move.1
./shtool install -c -m 644 shtool-install.1 /usr/local/share/man/man1/shtool-install.1
./shtool install -c -m 644 shtool-mkdir.1 /usr/local/share/man/man1/shtool-mkdir.1
./shtool install -c -m 644 shtool-mkln.1 /usr/local/share/man/man1/shtool-mkln.1
./shtool install -c -m 644 shtool-mkshadow.1 /usr/local/share/man/man1/shtool-mkshadow.1
./shtool install -c -m 644 shtool-fixperm.1 /usr/local/share/man/man1/shtool-fixperm.1
./shtool install -c -m 644 shtool-rotate.1 /usr/local/share/man/man1/shtool-rotate.1
./shtool install -c -m 644 shtool-tarball.1 /usr/local/share/man/man1/shtool-tarball.1
./shtool install -c -m 644 shtool-subst.1 /usr/local/share/man/man1/shtool-subst.1
./shtool install -c -m 644 shtool-platform.1 /usr/local/share/man/man1/shtool-platform.1
./shtool install -c -m 644 shtool-arx.1 /usr/local/share/man/man1/shtool-arx.1
./shtool install -c -m 644 shtool-slo.1 /usr/local/share/man/man1/shtool-slo.1
./shtool install -c -m 644 shtool-scpp.1 /usr/local/share/man/man1/shtool-scpp.1
./shtool install -c -m 644 shtool-version.1 /usr/local/share/man/man1/shtool-version.1
./shtool install -c -m 644 shtool-path.1 /usr/local/share/man/man1/shtool-path.1
./shtool install -c -m 644 shtool.m4 /usr/local/share/aclocal/shtool.m4
./shtool install -c -m 644 sh.common /usr/local/share/shtool/sh.common
./shtool install -c -m 644 sh.echo /usr/local/share/shtool/sh.echo
./shtool install -c -m 644 sh.mdate /usr/local/share/shtool/sh.mdate
./shtool install -c -m 644 sh.table /usr/local/share/shtool/sh.table
./shtool install -c -m 644 sh.prop /usr/local/share/shtool/sh.prop
./shtool install -c -m 644 sh.move /usr/local/share/shtool/sh.move
./shtool install -c -m 644 sh.install /usr/local/share/shtool/sh.install
./shtool install -c -m 644 sh.mkdir /usr/local/share/shtool/sh.mkdir
./shtool install -c -m 644 sh.mkln /usr/local/share/shtool/sh.mkln
./shtool install -c -m 644 sh.mkshadow /usr/local/share/shtool/sh.mkshadow
./shtool install -c -m 644 sh.fixperm /usr/local/share/shtool/sh.fixperm
./shtool install -c -m 644 sh.rotate /usr/local/share/shtool/sh.rotate
./shtool install -c -m 644 sh.tarball /usr/local/share/shtool/sh.tarball
./shtool install -c -m 644 sh.subst /usr/local/share/shtool/sh.subst
./shtool install -c -m 644 sh.platform /usr/local/share/shtool/sh.platform
./shtool install -c -m 644 sh.arx /usr/local/share/shtool/sh.arx
./shtool install -c -m 644 sh.slo /usr/local/share/shtool/sh.slo
./shtool install -c -m 644 sh.scpp /usr/local/share/shtool/sh.scpp
./shtool install -c -m 644 sh.version /usr/local/share/shtool/sh.version
./shtool install -c -m 644 sh.path /usr/local/share/shtool/sh.path
現(xiàn)在我們能在自己的shell腳本中使用這些函數(shù)咯熟妓。
shtool庫函數(shù)
函數(shù) | 描述 |
---|---|
Arx | 創(chuàng)建歸檔文件(包含一些擴展功能) |
Echo | 顯示字符串,并提供了一些擴展構(gòu)件 |
fixperm | 改變目錄樹的文件權(quán)限 |
install | 安裝腳本或文件 |
mdate | 顯示文件或目錄修改時間 |
mkdir | 創(chuàng)建一個或更多目錄 |
Mkln | 使用相對路徑創(chuàng)建鏈接 |
mkshadow | 創(chuàng)建一棵陰影樹 |
move | 帶有替換功能的文件移動 |
Path | 處理程序路徑 |
platform | 顯示平臺標(biāo)識 |
Prop | 顯示一個帶有動畫效果的進度條 |
rotate | 轉(zhuǎn)置日志文件 |
Scpp | 共享的C預(yù)處理器 |
Slo | 根據(jù)庫的類別栏尚,分離鏈接器選項 |
Subst | 使用sed的替換操作 |
Table | 以表格的形式顯示由字段分隔的數(shù)據(jù) |
tarball | 從文件和目錄中創(chuàng)建tar文件 |
version | 創(chuàng)建版本信息文件 |
每個shtool函數(shù)都包含大量的選項和參數(shù)起愈。下面是使用格式:
shtool [option] [function [option] [args]]
使用庫
我們能直接在命令行或者在自己構(gòu)建的腳本中使用shtool的函數(shù)。
下面是在腳本中使用的簡單例子:
wsx@wsx:~/tmp$ cat test13
#!/bin/bash
shtool platform
wsx@wsx:~/tmp$ ./test13
Ubuntu 17.10 (AMD64)
platform
函數(shù)會返回Linux發(fā)行版以及系統(tǒng)使用的CPU硬件相關(guān)信息译仗。
prop
函數(shù)可以使用\
,|
,/
和-
字符創(chuàng)建一個旋轉(zhuǎn)的進度條抬虽。它可以告訴shell腳本用戶目前正在處理一些后臺處理工作。
wsx@wsx:~/tmp$ ls -al /usr/bin | shtool prop -p "waiting..."
waiting...
在腳本學(xué)習(xí)中涉及到諸多的符號纵菌,在運行時我們可能會感覺到順利阐污,但自己寫的時候往往會用不太對,推薦閱讀一下常用的一些符號區(qū)分咱圆,像小括號笛辟、中括號粘优、花括號等等黑低。覺的不懂的可以看看Linux_Bash腳本_單引號’雙引號“”反引號`小括號()中括號[]大括號{}以及相關(guān)的百度資料萎胰。