日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
Linux下復(fù)用外部shell腳本

Linux開發(fā)中,經(jīng)常會編寫shell腳本來執(zhí)行一些任務(wù),通常是一個腳本只做一件事,隨著任務(wù)的增加,腳本會越來越多,可復(fù)用的地方也會逐漸增加,這時就需要提取出腳本中的公共的功能放到一個通用的腳本中,其他腳本都能復(fù)用它

10年積累的成都網(wǎng)站制作、成都網(wǎng)站設(shè)計(jì)經(jīng)驗(yàn),可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識你,你也不認(rèn)識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有蕉嶺免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

在Linux開發(fā)中,經(jīng)常會編寫shell腳本來執(zhí)行一些任務(wù),通常是一個腳本只做一件事,隨著任務(wù)的增加,腳本會越來越多,可復(fù)用的地方也會逐漸增加,這時就需要提取出腳本中的公共的功能放到一個通用的腳本中,其他腳本都能復(fù)用它

本篇文章介紹shell腳本中如何執(zhí)行外部腳本,如何調(diào)用外部腳本中的函數(shù),以及腳本復(fù)用相關(guān)的方法

執(zhí)行外部腳本的方式

假如在當(dāng)前目錄有 a.sh 腳本,內(nèi)容如下

#!/bin/bash 
echo "a.sh..."

在一個腳本中執(zhí)行外部腳本主要有以下幾種方式

source 外部腳本名字

在當(dāng)前目錄下的 b.sh 腳本,內(nèi)容如下:

#!/bin/bash 
source a.sh
echo "b.sh..."

執(zhí)行 ./b.sh,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
a.sh...
b.sh...

腳本中 source a.sh 命令 會先執(zhí)行當(dāng)前目錄下的 a.sh腳本,所以結(jié)果會先輸出 a.sh…再輸出 b.sh腳本本身的打印

點(diǎn)號 外部腳本名字

把 b.sh 腳本中執(zhí)行a.sh腳本的語句修改成 點(diǎn)號 + 空格 + a.sh ,修改之后的腳本內(nèi)容如下:

注意:點(diǎn)號和a.sh之間一定要加上空格,否則執(zhí)行的時候會出錯

#!/bin/bash 
. a.sh
echo "b.sh..."

執(zhí)行 ./b.sh,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
a.sh...
b.sh...

在上述腳本中, . a.sh 會先執(zhí)行a.sh腳本, 結(jié)果會先輸出 a.sh…再輸出 b.sh…

sh 外部腳本名字

sh 外部腳本名字 和 ./外部腳本名字 兩種方式是一樣的,選擇哪一種方式都沒問題,下面是以前面一種方式為例說明的

把 b.sh 腳本中 source a.sh修改成 sh a.sh ,修改之后的腳本內(nèi)容如下:

#!/bin/bash 
sh a.sh
echo "b.sh..."

執(zhí)行 ./b.sh 命令, 結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
a.sh...
b.sh...

可以看出,結(jié)果輸出和上面兩種方式是一樣的

三種方式的有什么區(qū)別 調(diào)用外部腳本有 source 外部腳本 、點(diǎn)號 外部腳本、sh 外部腳本 三種方式,它們之間有什么區(qū)別呢?

其中,source 外部腳本 和 點(diǎn)號 外部腳本 兩種方式是相同的,當(dāng)前腳本繼承了外部腳本的全局變量和函數(shù), 相當(dāng)于把外部腳本的函數(shù)和全局變量導(dǎo)入了當(dāng)前腳本中

修改 a.sh 和 b.sh 腳本, 內(nèi)容如下

a.sh腳本

#!/bin/bash 
VAR_A=10

func_a()
{
 echo "a.sh...pid:$$,param:$1"
}

b.sh腳本

#!/bin/bash 
source a.sh

func_a $1
echo "vara:$VAR_A"
echo "b.sh...pid:$$"

執(zhí)行 ./b.sh 5 命令,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh 5
a.sh...pid:21485,param:5
vara:10
b.sh...pid:21485

兩個腳本中的 $$ 是指執(zhí)行腳本的進(jìn)程ID,從結(jié)果可以看出,a.sh 和 b.sh 都是在同一個進(jìn)程內(nèi)執(zhí)行的,所以在 b.sh 腳本中執(zhí)行 source a.sh 命令,會把 a.sh 腳本中的全局變量 VAR_A 和函數(shù) func_a導(dǎo)入到 b.sh中

在 b.sh中打印變量 VAR_A,輸出的值和 a.sh中相同,調(diào)用 func_a函數(shù),輸出也說明了調(diào)用的是 a.sh中的函數(shù)

source 外部腳本 、點(diǎn)號 外部腳本 兩種方式是相同的, 所以, 把 b.sh 中 source a.sh 修改成 . a.sh , 執(zhí)行 ./b.sh 5, 結(jié)果依然是相同的

由于 sh 外部腳本的方式是當(dāng)前腳本和外部腳本在兩個不同的進(jìn)程中執(zhí)行,所以當(dāng)前腳本不能直接使用外部腳本中的函數(shù)和全局變量

修改 a.sh 和 b.sh 腳本, 內(nèi)容如下

a.sh腳本

#!/bin/bash 
test_a()
{
 echo "a.sh...test_a"
}

echo "a.sh...pid:$$"

b.sh腳本

#!/bin/bash 
sh a.sh

echo "b.sh...pid:$$"

test_a

執(zhí)行 ./b.sh 命令,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
a.sh...pid:21818
b.sh...pid:21817

./b.sh:行7: test_a: 未找到命令 從結(jié)果可以看出,執(zhí)行 a.sh 和 b.sh 的進(jìn)程ID是不同的,b.sh腳本進(jìn)程找不到test_a函數(shù),所以在b.sh中調(diào)用test_a 函數(shù)會提示 未找到命令

調(diào)用外部腳本中的函數(shù)

上一節(jié)講到 sh 外部腳本 的方式無法直接使用外部腳本中函數(shù)和全局變量,下面提供幾種方法可以解決這個問題

case 分支選擇

這種方法類似于程序代碼中的 switch case 語句,通過switch 選擇不同的分支從而執(zhí)行不同的邏輯,shell腳本中是使用case關(guān)鍵字來實(shí)現(xiàn)的

a.sh腳本

#!/bin/bash 
VAR_A=10

test_a()
{
  echo "test_a..pid:$$,p1:$1,p2:$2"
}
get_var()
{
 echo ${VAR_A}
}

case "$1" in
   ta)
     test_a $2 $3
     ;;
   var)
     get_var
     ;;
  *)
     echo "parameter err..."
esac

b.sh腳本

#!/bin/bash 
echo "b.sh...pid:$$"

sh a.sh ta 3 5

ret=$(sh a.sh var)

echo "ret:$ret"

執(zhí)行 ./b.sh 命令,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
b.sh...pid:24813
test_a..pid:24814,p1:3,p2:5
ret:10

腳本b.sh一開始打印了調(diào)用自身的進(jìn)程ID

sh a.sh ta 3 5 語句是調(diào)用a.sh腳本,傳入的三個參數(shù)分別是ta, 3, 5 ,執(zhí)行a.sh時,傳入的第一個參數(shù) ta經(jīng)過case匹配之后調(diào)用 test_a函數(shù),并把剩下的兩個參數(shù) 3和5作為參數(shù)傳入函數(shù)

ret=語句時調(diào)用腳本,傳入一個參數(shù),經(jīng)過匹配之后調(diào)用函數(shù),該函數(shù)的作用輸出腳本中全局變量的值,語句中()的作用是獲取()中命令的返回值,這里是把a(bǔ).sh腳本中 get_var函數(shù)的返回值賦值給 ret變量,所以該變量的值是 a.sh腳本中全局變量VAR_A的值

說明:如果想要獲取函數(shù)的返回值,可以在函數(shù)中用 echo 打印相應(yīng)的輸出值,然后使用函數(shù)名參數(shù)列表可以獲取到函數(shù)中打印的值,如上面腳本中(sh a.sh var)語句,變量ret的值是 a.sh腳本中 get_var函數(shù)輸出的值10

這里需要注意的是, 如果函數(shù)中有echo調(diào)試日志,那么調(diào)試日志也會一起返回

函數(shù)調(diào)用模板

上面介紹的用 case 關(guān)鍵字去匹配調(diào)用不同的函數(shù)有一個缺點(diǎn),每次a.sh腳本中增加一個函數(shù)的時候,case 就需要添加一個分支,分支里調(diào)用不同的函數(shù),還需要注意函數(shù)是否有參數(shù)傳入以及參數(shù)數(shù)量是否正確

我們可以在每個供外部調(diào)用腳本的尾部加上以下的語句,就可以解決上述問題, 具體語句如下

if [ $# -ge 1 ]; then
  name="$1"
  shift 1
  $name "$@"
fi

上述語句首先判斷調(diào)用腳本時傳入的參數(shù)數(shù)量,只有參數(shù)數(shù)量大于等于1才有效,傳入的第一個參數(shù)表示函數(shù)名字,從第二個參數(shù)到最后一個參數(shù)都會作為參數(shù)傳入到函數(shù)中

這里的 shift 1 是把傳入腳本的參數(shù)左移一個位置,比如:傳入腳本參數(shù)有 2 三個參數(shù),左移一個位置之后,2 移動到 的位置,3 移動到 $2 的位置,參數(shù)數(shù)量變?yōu)?了

原因: 傳入腳本的參數(shù)中,第一個參數(shù)是函數(shù)名字,從第二個參數(shù)起才是函數(shù)的參數(shù),如果不做左移處理,第一個參數(shù)函數(shù)名字也會作為參數(shù)傳入到函數(shù)中

下面是完整的腳本內(nèi)容

a.sh腳本

#!/bin/bash 
VAR_A=10

test_a()
{
  echo "test_a..pid:$$,p1:$1,p2:$2"
}

get_var()
{
 echo ${VAR_A}
}

if [ $# -ge 1 ]; then
  name="$1"
  shift 1
  $name "$@"
fi

b.sh腳本

#!/bin/bash 
echo "b.sh...pid:$$"

sh a.sh test_a 3 5

ret=$(sh a.sh get_var)

執(zhí)行 ./b.sh 命令,結(jié)果如下

[root@ecs-centos-7 ~]# ./b.sh
b.sh...pid:25086
test_a..pid:25087,p1:3,p2:5
ret:10

可以看出,結(jié)果和上面 case 的方法是一樣的

現(xiàn)在其他腳本中都可以通過 sh a.sh 函數(shù)名 參數(shù)列表 這樣的方式調(diào)用 a.sh 腳本中的函數(shù)了,通過 $(sh a.sh 函數(shù)名 參數(shù)列表)的方式獲取 a.sh腳本函數(shù)的返回值

兩者的優(yōu)缺點(diǎn)

與case分支選擇的方式相比,函數(shù)調(diào)用模板的優(yōu)點(diǎn)是調(diào)用者只需要關(guān)心復(fù)用的腳本中函數(shù)名、函數(shù)傳入?yún)?shù)、函數(shù)返回值就可以直接使用

缺點(diǎn)是如果有多個腳本都調(diào)用了復(fù)用腳本中的函數(shù),當(dāng)復(fù)用腳本中函數(shù)名變更時,需要修改所有調(diào)用了它的地方

函數(shù)調(diào)用模板方式的缺點(diǎn)恰恰是case分支選擇方式的有點(diǎn),case分支選擇的方式時根據(jù)傳入的字符串參數(shù)調(diào)用不同的函數(shù),這里的字符串參數(shù)相當(dāng)于函數(shù)的別名,只要這個參數(shù)保持不變,腳本中的函數(shù)名字可以任意變更

上述的優(yōu)缺點(diǎn)比較只是一個相對的比較,實(shí)際應(yīng)用中下不會很明顯,大部分情況兩種方式都可以使用

小結(jié)

在編寫shell腳本的過程中,經(jīng)常會遇到一些莫名奇妙的問題,有些問題就算撓破頭皮都不知道如何解決,腳本復(fù)用可以把一些公共功能提取出來,形成一個個的功能模塊,不僅有助于減少我們編寫腳本時犯的錯誤,而且對后期的腳本維護(hù)很有幫助


標(biāo)題名稱:Linux下復(fù)用外部shell腳本
標(biāo)題來源:http://www.5511xx.com/article/cceisog.html