Bash 什麼時候會給 HOME 賦初始值

2021-09-07 03:38:28 字數 1360 閱讀 8190

今天無意發現下面這個表現:

$  env -i bash -c cd

bash: line 0: cd: home not set

$ env -i bash -c 'echo $home'

這表明了,bash 只會從環境變數中繼承 home 變數,從來不自己初始化它?為了證實這個想法,我去翻了下原始碼,發現其實並不是,在一種情況下,bash 是會主動初始化 home 變數的:

if (login_shell == 1 && posixly_correct == 0

) set_home_var ();

從這句原始碼看出,bash 只有在當前 shell 是個登陸 shell 且不在 posix 模式中時,才可能去給 home 賦初始值。然後我就試驗了一下:

$  env -i bash --login -c 'echo $home'

握草,為什麼還沒有值?遂谷歌了一下,發現 14 年有人報了個 bug 看了這個 bug 後我明白了,原來在 bash 內部,登陸 shell 還分三種情況:

/*

non-zero means that this shell is a login shell.

specifically:

0 = not login shell.

1 = login shell from getty (or equivalent fake out)

-1 = login shell from "--login" (or -l) flag.

-2 = both from getty, and from flag. */

int login_shell = 0;

一種是 bash 的父程序啟動 bash 時傳入的第 0 個引數(通過 exec* 函式指定)的第乙個字元是以 - 開頭的情況,一種是 bash 啟動時用了 --login 或 -l 選項的情況,最後一種是上面兩種表現混合的情況,login_shell 變數的值分別為 1、-1、-2,但從剛才看的原始碼看出,只有在 login_shell 為 1 的情況下,bash 才會初始化 home 變數。那麼我們再次驗證一下:

$ exec -ca -whatever bash -c 'echo $home'

/home/admin

這條命令用到了 exec 的 -a 選項來指定 argv[0]。我們還可以自己寫個 c 程式驗證一下:

$ cat a.c

#include

int main() ;

char *envp[ ] = ;

execve("/bin/bash", argv, envp);

$ gcc a.c -o a

$ ./a

/home/admin

什麼時候用exists 什麼時候用in

in not in exists not exists 使用exists,oracle會首先檢查主查詢,然後執行子查詢直到它找到第乙個匹配項,這就節省了時間。oracle在執行in子查詢時,首先執行 子查詢,並將獲得的結果列表存放在乙個加了索引的臨時表中。在執行子查詢之前,系統先將主查詢掛起 待子查...

什麼時候用GET?什麼時候用POST?

get和post兩種方法都是將資料送到伺服器,但你該用哪一種呢?http標準包含這兩種方法是為了達到不同的目的。post用於建立資源,資源的內容會被編入http請示的內容中。例如,處理訂貨表單 在資料庫中加入新資料行等。當請求無 時 如進行搜尋 便可使用get方法 當請求有 時 如新增資料行 則用p...

什麼時候用堆,什麼時候用棧?

參考文章 c 面試題之記憶體分配 一 首先,回顧一下c c 的記憶體分配機制。乙個c c 程式編譯時記憶體分為5大儲存區 堆區 棧區 靜態區 全域性區 文字常量區 儲存字串常量 程式 區 存放二進位制程式 下面主要闡述前面三個。1 靜態儲存區域 靜態儲存區域的 內存在程式編譯時就已經分配好,這塊內存...