Shell中調用外部腳本的若干種方式

在運行shell腳本時候,有三種方式來調用外部的腳本,exec(exec script.sh)方式、source(source script.sh)方式、fork(./script.sh)方式。

fork方式

通常情況下在系統中通過相對路徑或絕對路徑執行一個命令時,都會由父進程開啓一個子進程,當子進程結束後再返回父進程,這種行爲過程就叫fork。當腳本中正常調用一個外部命令或其他腳本時,都會fork一個子shell進程,我們的命令會運行在這個子shell中。

subshell.sh

#!/bin/bash

#使用&在後臺進程開啓子shell

count=0

for i in {1..254}
do
  ping -c1 -i0.2 -WL 192.168.43.$i >/dev/null && let count++ &
done

echo $count

for_test.sh

#!/bin/bash

sleep 5

#絕對路徑或相對路徑調用外部腳本時會fork子進程
/home/minger/share/shell/subshell.sh

這個腳本在執行的過程中會打開一個終端窗口,反覆執行pstree可以獲得如下的進程樹信息。可以看出,我們腳本調用一個外部命令時(sleep)時,系統會fork一個子shell,sleep命令是在子shell中執行的。

當腳本通過相對路徑或者絕對路徑調用外部其他腳本時,會fork一個子進程,並且subshell.sh腳本中命令被觸發執行時也會再次fork子進程。

可以用pstree查看:

在這裏插入圖片描述

在這裏插入圖片描述
使用fork方式開啓的子進程是父進程的一個副本,因此會自動單向繼承父進程的環境,如環境變量、資源權限、內存中的數據、信號等等。但是,父進程無法繼承子進程環境。

exec方式

使用exec方式調用其他命令或腳本時,系統不會開啓子進程,而是使用新的程序替換當前的shell環境,因爲當前shell被替換了,所以當exec調用的程序結束後,當前環境會被關閉。

exec執行命令流程圖:
在這裏插入圖片描述
上面的圖中,通過exec時執行ls命令,一個是使用用echo命令讓屏幕回顯一個字符串信息,最後一個是cd 命令,用於切換目錄。但是,第一命令使用exec調用ls,系統使用ls命令替換當前的腳本,整個進程就變成了一個ls命令,當ls命令結束後進程也就結束了。

下面來看看例子:

#!/bin/bash

exec ls
echo "test"

cd /shell

在這裏插入圖片描述

這裏有個特例,當exec後面的參數文件重定向時,不會替換當前的shell環境,腳本後續其他命令也不會受到任何影響。

source方式

使用source或者“.”來調用外部腳本,不會產生新的進程,繼承當前shell環境變量,而且被調用的腳本運行結束後,它擁有的環境變量和聲明變量會被當前shell保留,類似將調用腳本的內容複製過來直接執行。執行完畢後原主shell繼續運行。

下面來看個簡單例子:

tmp.sh

#!/bin/bash

env="Minger"

source.sh

#!/bin/bash

source /tmp/tmp.sh

echo "hi,$env"

ls /

在這裏插入圖片描述

在上面的source.sh腳本中使用source命令加載/tmp/tmp.sh腳本,source命令會在不開啓shell情況下,將tmp.sh中的所有命令加載當前shell環境中,類似tmp.sh文件中的所有命令編寫在source.sh文件中的一樣。

在這裏插入圖片描述
歡迎關注公衆號【程序猿編碼】,添加本人微信號(17865354792),回覆:領取學習資料。或者回復:進入技術交流羣。網盤資料有如下:

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章