Bash 何时会给 HOME 赋初始值

今天无心发现下面这个表现:html

$  env -i bash -c cdshell

bash: line 0: cd: HOME not setbash

$ env -i bash -c 'echo $HOME'函数

 

这代表了,Bash 只会从环境变量中继承 HOME 变量,历来不本身初始化它?为了证明这个想法,我去翻了下源码,发现其实并非,在一种状况下,Bash 是会主动初始化 HOME 变量的:ui

if (login_shell == 1 && posixly_correct == 0)
  set_home_var ();

从这句源码看出,Bash 只有在当前 Shell 是个登录 Shell 且不在 Posix 模式中时,才可能去给 HOME 赋初始值。而后我就试验了一下:this

$  env -i bash --login -c 'echo $HOME'spa

 

握草,为何尚未值?遂谷歌了一下,发现 14 年有人报了个 bug https://lists.gnu.org/archive/html/bug-bash/2014-01/msg00063.html。看了这个 bug 后我明白了,原来在 Bash 内部,登录 Shell 还分三种状况:code

/* 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 变量的值分别为 一、-一、-2,但从刚才看的源码看出,只有在 login_shell 为 1 的状况下,Bash 才会初始化 HOME 变量。那么咱们再次验证一下:htm

$ exec -ca -whatever bash -c 'echo $HOME'blog

/home/admin

这条命令用到了 exec 的 -a 选项来指定 argv[0]。咱们还能够本身写个 c 程序验证一下:

$ cat a.c

#include<unistd.h>

int main() {

  char *argv[ ] = { "-whatever", "-c", "echo $HOME", NULL };

  char *envp[ ] = { NULL };

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

}

$ gcc a.c -o a

$ ./a

/home/admin

相关文章
相关标签/搜索