即便 Bash 没有从父进程继承任何的环境变量,Bash 自己也会创建三个环境变量,分别是:
$ env -i bash -c export declare -x OLDPWD declare -x PWD="/" declare -x SHLVL="1" |
SHLVL
如果父进程传递了 SHLVL 环境变量,那么 Bash 会在那个值的基础上累加 1,如果没有传,则赋初始值 1:
$ env -i SHLVL=22 bash -c 'echo $SHLVL' # 原值基础上累加 1 23 $ env -i bash -c 'echo $SHLVL' # 赋初始值 1 1 |
PWD
如果父进程传递了 PWD 环境变量,且该环境变量的值是当前目录的路径,且是个绝对路径,则 Bash 会直接继承这个值,否则 Bash 会自己调用 getcwd C 函数获取当前工作目录赋值给 PWD。
$ env -i PWD=/ bash -c 'echo $PWD' # 直接继承,没有调用 getcwd C 函数 / $ env -i PWD=/etc bash -c 'echo $PWD' # 不是当前目录的路径,自己给 PWD 赋值 / $ env -i PWD=. bash -c 'echo $PWD' # 是当前目录的路径,但是是个相对路径,自己给 PWD 赋值 / |
OLDPWD
如果父进程传递了 OLDPWD 环境变量,Bash 会直接清空这个变量的值。
$ env -i OLDPWD=/etc bash -c 'echo $OLDPWD' $ env -i OLDPWD=/etc ksh -c 'echo $OLDPWD' /etc $ env -i OLDPWD=/etc csh -c 'echo $OLDPWD' /etc $ env -i OLDPWD=/etc zsh -c 'echo $OLDPWD' / |
可见不同于 Bash,ksh 和 csh 会直接继承那个值,而 zsh 会用当前工作目录的值改写继承来的 OLDPWD 变量的值。
有人在 bug-bash 上提了这个问题 http://lists.gnu.org/archive/html/bug-bash/2015-11/msg00115.html,Bash 作者表示会在下个版本尝试改变这个行为,但并不是照抄 ksh 和 csh 的做法,ksh 和 csh 只是简单的继承了 OLDPWD 的值,并不判断那个值是不是个合法的且存在的目录的路径:
$ env -i OLDPWD=2333 ksh -c 'echo $OLDPWD' 2333 $ env -i OLDPWD=2333 csh -c 'echo $OLDPWD' 2333 |
而 Bash 作者表示他准备判断一下,如果是合法目录路径的话,才会继承。