2016-06-23 25 views
0

我試圖訪問前一個命令(在Makefile中)聲明的變量。在Makefile命令中聲明的訪問變量

這裏的Makefile

all: 
    ./script1.sh 
    ./script2.sh 

這裏的腳本聲明我要訪問的變量,script1.sh

#!/usr/bin/env bash 
myVar=1234 

這裏的腳本試圖訪問先前定義的變量,script2.sh

#!/usr/bin/env bash 
echo $myVar 

Un幸運的是,當我運行make時,myVar無法訪問。有沒有其他方法?謝謝。

回答

2

Make將在其自己的shell中運行每個shell命令。而當炮彈退出時,其環境就會喪失。

如果你想讓一個腳本的變量在下一個腳本中可用,那麼就有這樣的構造。例如:

all: 
    (. ./script1.sh; ./script2.sh) 

這會導致Make啓動一個shell來處理這兩個腳本。

還請注意,您將需要export該變量才能在第二個腳本中可見;未導出的變量僅適用於本地腳本,不適用於它啓動的子殼。


UPDATE(每Kusalananda的評論):

如果你希望你的shell命令來填充MAKE變量,而不僅僅是環境變量,你可能有依賴於版本製作的,你是選擇運行。例如,在BSD make和GNU make,你可以使用 「變量賦值修飾語」 包括(從BSD make的手冊頁):

!=  Expand the value and pass it to the shell for execution and 
     assign the result to the variable. Any newlines in the result 
     are replaced with spaces. 

因此,BSD make和GNU make,你可以這樣做:

$ cat Makefile 

foo!= . ./script1.sh; ./script2.sh 

all: 
    @echo "foo=${foo}" 

$ 
$ cat script1.sh 
export test=bar 
$ 
$ cat script2.sh 
#!/usr/bin/env bash 

echo "$test" 
$ 
$ make 
foo=bar 
$ 

注意script1.sh不包括任何家當,因爲它是來源,因此在調用的shell中運行,不管它是什麼。這使得shebang線只是一個評論。如果你的系統默認shell是POSIX而不是bash(比如Ubuntu,Solaris,FreeBSD等),這應該仍然可以工作,因爲POSIX shell應該都理解導出變量的概念。

+0

這很好。但是,這些變量在'(...)'創建的shell之外是不可用的。這對於OP來說可能不是問題,但嚴格來說,這與使用script3.sh來源化第一個腳本並執行第二個腳本是一樣的。這一點不再是「在Makefile中」。 – Kusalananda

+1

@Kusalananda - 更新了一個在BSD和GNU make中填充變量的解決方案。不適用於所有變體,但至少它是某種東西。 :) – ghoti

+0

這是一個很好的解決方案。 – Kusalananda

1

這兩個獨立的腳本調用創建兩個獨立的環境。第一個腳本在其環境中設置變量並退出(環境丟失)。第二個腳本在其環境中沒有該變量,所以它輸出一個空字符串。

環境變量不能在父shell與其子shell之間的環境之間傳遞(而不是相反)。傳遞給子shell的變量僅爲那些父shell具有export -ed的變量。因此,如果第一個腳本調用第二個腳本,則會輸出該值(如果是第一個腳本中的export -ed)。

在一個shell中,你需要source第一個文件來設置當前環境中的變量(然後是export!)。但是,在Makefiles中,由於沒有方便的source命令,所以它有點棘手。您可能需要閱讀this StackOverflow question

編輯在光@ ghoti的回答:@ghoti有一個很好的解決方案,但我會離開我的答案在這裏,因爲它解釋多一點冗長有關環境變量和我們能做些什麼,而不是與他們無關關於在環境之間傳遞它們。

+0

這就是我認爲,非常感謝 – julesbou