【shell筆記>腳本】創(chuàng)建和使用shell函數(shù)

來源: 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)的百度資料萎胰。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末势木,一起剝皮案震驚了整個濱河市王财,隨后出現(xiàn)的幾起案子涩笤,更是在濱河造成了極大的恐慌痛垛,老刑警劉巖皇帮,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匈睁,死亡現(xiàn)場離奇詭異监透,居然都是意外死亡,警方通過查閱死者的電腦和手機航唆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進店門胀蛮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人佛点,你說我怎么就攤上這事醇滥。” “怎么了超营?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵鸳玩,是天一觀的道長。 經(jīng)常有香客問我演闭,道長不跟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任米碰,我火速辦了婚禮窝革,結(jié)果婚禮上购城,老公的妹妹穿的比我還像新娘。我一直安慰自己虐译,他們只是感情好瘪板,可當(dāng)我...
    茶點故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著漆诽,像睡著了一般侮攀。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上厢拭,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天兰英,我揣著相機與錄音,去河邊找鬼供鸠。 笑死畦贸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的楞捂。 我是一名探鬼主播薄坏,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼泡一!你這毒婦竟也來了颤殴?” 一聲冷哼從身側(cè)響起觅廓,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鼻忠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后杈绸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帖蔓,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年瞳脓,在試婚紗的時候發(fā)現(xiàn)自己被綠了塑娇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,040評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡劫侧,死狀恐怖埋酬,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情烧栋,我是刑警寧澤写妥,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站审姓,受9級特大地震影響珍特,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜魔吐,卻給世界環(huán)境...
    茶點故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一扎筒、第九天 我趴在偏房一處隱蔽的房頂上張望莱找。 院中可真熱鬧,春花似錦嗜桌、人聲如沸奥溺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谚赎。三九已至,卻和暖如春诱篷,著一層夾襖步出監(jiān)牢的瞬間壶唤,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工棕所, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留闸盔,地道東北人。 一個月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓琳省,卻偏偏與公主長得像迎吵,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子针贬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,979評論 2 355

推薦閱讀更多精彩內(nèi)容