1. 程式人生 > >Linux shell指令碼中父子程序與變數的分析

Linux shell指令碼中父子程序與變數的分析

轉載地址:https://site.douban.com/196781/widget/notes/12220452/note/261008964/

【問題】一個 test.sh 裡面這麼寫
#! /bin/bash
read test
echo $test
exit 0
儲存, chmod +x test.sh
./test.sh
譬如輸入 ok, 指令碼就輸出 ok
然後在 shell 下
直接 echo $test 卻沒有輸出 ok...
這是怎麼回事?這個自定義的變數不能同時使用麼?
【分析】
問題的現象是在外部shell中echo $test輸出了一個空值,考慮到給test賦值是在指令碼程式中進行的,因此指令碼做如下改動進行測試


第7行程式碼打印出當前程序ID。第8行程式碼打印出當前程序ID及父程序ID。

【現象描述】:
1.echo $$顯示當前登入shell程序ID為2663;
2.執行指令碼檔案,分隔符第一行顯示登入shell派生出一個程序ID為2783的shell執行程序;該程序負責掃描shell指令碼進行執行;
3.程序2783指令碼執行程序負責逐行執行指令碼,遇到可執行程式就派生新的子程序來執行,程序號為2784和2785的程序都是執行shell 2783 程序派生的子程序ps和grep .
【結果解釋】
使用者登入到Linux系統後,系統將啟動一個使用者shell。在這個shell中,可以使用shell命令或宣告變數,也可以建立並執行shell指令碼程式。shell執行外部命令或執行shell指令碼程式時,系統將建立一個子shell,然後在子Shell中執行此Shell指令碼 。一旦子Shell中的指令碼執行完畢,此子Shell隨即結束,返回到父Shell中,但不會影響父Shell原本的環境。這就是解釋了為什麼在登入shell中echo顯示空值;
【解決辦法】
解決問題的思路有兩個。第一,在當前shell執行指令碼;第二,將子shell變數傳遞給父shell。
現在考慮第第一個思路:如果要想在當前shell中執行指令碼,而不派生子shell,經查閱可以使用. ./test.sh 或者 source ./test.sh命令來執行。(注意第一個點之間的空格)

結果顯示使用. ./test.sh命令可以直接在當前shell中執行了指令碼程式。這時可以直接在的登入shell中顯示變數。
最後測試結果,驗證了假設。

PS:關於export
1.一個shell中的系統環境變數會被複制到子shell中(用export定義的變數);
2.一個shell中的系統環境變數只對該shell或者它的子shell有效,該shell結束時變數消失(並不能返回到父shell中)。
3.不用export定義的變數只對該shell有效,對子shell也是無效的。