2016-02-04 26 views
0

(Disclamer:這是作業)全局靜態int在自我調用模塊中

我正在創建一個shell程序,我們稱之爲fancysh。我正在嘗試將PATH(和其他env vars)功能添加到我的shell中,到目前爲止都很好。我天真的做法是將所有這些變量作爲靜態變量存儲在fancysh.c中。但是現在我試圖實現保存shell的當前「深度」的環境變量SHLVL。例如,我可以在fancysh的第一個實例中運行,並且SHLVL應該讀取1,在再次調用fancysh時,SHLVL應該增加(並且在shell退出時遞減)。

我已經試過......

fancysh.h

#ifndef FANCYSH_H 
#define FANCYSH_H 

extern int SHLVL; 

#endif 

fancysh.c

#include "fancysh.h" 

int SHLVL; 

int main(){ 

/* some fancy code to determine if SHLVL is initalized */ 
/* if not init to 0 */ 

SHLVL ++; 
printf("%d\n", SHLVL); 

/* Test Code Only */ 
int pid = fork(); 
if(pid == 0 && SHLVL < 10) 
    exec("fancysh"); 
wait(); 
/* Test Code Only */ 

/* shell code */ 
SHLVL--; 
printf("%d\n", SHLVL); 
exit(0); 
} 

我以前的答案herehere作爲其中的一部分解。

那麼我該如何去實現花哨的代碼來確定SHLVL是否被初始化?我對使用#ifdef#define的組合有一些想法,但我不是100%確定如何做到這一點。

+0

注意:混淆通常是一個非常糟糕的主意。在這裏你混淆了關鍵字'extern'。你爲什麼這樣做?在可預見的將來,這是不太可能改變的。 – Olaf

+0

這樣做是爲了讓SHLVL只在外部申報一次。 –

+0

同一個變量的多個'extern'聲明不是固有的問題,既不在相同的翻譯單元中,也不在相同的程序或庫中提供不同的翻譯單元。 –

回答

0

您需要掌握一個事實,即不同的shell進程是不同的進程。僅僅因爲shell的另一個實例在shell的另一個實例範圍內啓動並不意味着前者會自動從後者中繼承任何數據。

還是沒有直接的,反正。任何新的shell實例都會從啓動它的進程中接收一個環境。如果該環境包含SHLVL變量,那麼新的shell進程當然可以讀取該值,並且它可能在其自己的作用域內呈現該環境變量的不同值。

+0

那麼你是否暗示我不應該試圖在我的shell進程中同步變量,而應該考慮將env vars作爲命令行參數傳遞給每個shell進程? –

+0

@CallbackKid,沒有人對命令行參數進行任何說明。我說你的shell的一個實例可以依靠其父進程提供給它的* environment *。它不能在任何情況下在實例中共享* SHLVL的存儲空間,因爲不同的實例可能需要維護不同的值。 –