[英]Variable scope in the shell level
最近我一直在閱讀高級Bash腳本 ,我發現一些關於父殼和子殼之間的變量范圍的東西讓我非常困惑。 這里是:
場景:有一些方法可以產生子shell:首先, (command-lists)
; 第二,執行非內置命令或腳本,依此類推。
因為當我們在父腳本中運行腳本時,子腳本無法在父shell中看到變量。 為什么在(command-lists)
結構中子shell可以看到父shell中的變量。 例如
(命令列表)
$ a=100 $ (echo $a) 100 $
運行一個腳本
$ cat b.sh echo $a $ a=100 $ ./b.sh # empty
怎么樣?
如果您在原始腳本中運行了子shell:
(command1; command2; ...)
子shell是fork()
創建的原始shell的直接副本,因此可以直接訪問其自己可用的所有原始變量的副本。
假設子shell中的命令( command1
, command2
等)本身就是shell腳本。 這些命令由子shell調用fork()
然后exec()
以創建新shell,新shell不會從原始shell繼承未導出的變量。
直接解決您的示例:
$ a=100
$ (echo $a)
100
$
這里,子shell有自己的所有變量(特別是a
)的副本,父變量可以訪問它們。 當然,子shell中所做的任何更改都不會反映在父shell中,因此:
$ a=100
$ (echo $a; a=200; echo $a)
100
200
$ echo $a
100
$
現在你的第二個例子:
$ cat b.sh
echo $a
$ a=100
$ ./b.sh
$ . ./b.sh
100
$ source ./b.sh
100
$ a=200 ./b.sh
200
$ echo $a
100
$ export a
$ ./b.sh
100
$
變量a
未導出,因此第一次運行b.sh
,它沒有$a
值,因此它回顯一個空行。 第二個例子是'作弊'; shell讀取腳本b.sh
,就好像它是當前shell的一部分(沒有fork()
)所以變量仍然可以被b.sh
訪問,因此它每次都回顯100。 (Dot或.
是在當前shell中讀取腳本的舊機制;第7版UNIX中的Bourne shell使用它。 source
命令是從C shell中借用的等效機制。)
命令a=200 ./b.sh
出口a
用於命令的持續時間,所以b.sh
看到並相呼應的修改值200
但主要殼具有a
不變。 然后當a
導出時,它可以自動用於b.sh
,因此它可以看到並回顯最后100個。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.