zoukankan      html  css  js  c++  java
  • Bash 什么时候会给 HOME 赋初始值

    今天无意发现下面这个表现:

    $  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 https://lists.gnu.org/archive/html/bug-bash/2014-01/msg00063.html。看了这个 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<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

  • 相关阅读:
    Makefile使用函数
    Makefile条件判断
    Makefile使用变量
    Makefile书写命令
    Makefile书写规则
    Makefile总述
    Makefile基础知识
    LEETCODE刷题 替换空格
    LEETCODE刷题 二维数组查找
    【Intellij IDEA 奇淫技巧】自动生成serialVersionUID的设置
  • 原文地址:https://www.cnblogs.com/ziyunfei/p/4959566.html
Copyright © 2011-2022 走看看