bash(exec -c 及 ENV_SUPATH)

验证问题以及发现问题 验证 manual page 中 exec -c command 不会开启新进程,但环境变量为空。
验证方式:

  1. 打印进程id echo $BASHPID
  2. 打印环境变量PATH echo $PATH
  3. 【bash(exec -c 及 ENV_SUPATH)】打印所有环境变量 export -p
    // 文件 test1 #!/usr/bin/bash set -e ./test2// 文件 test2 #!/usr/bin/bash set -e echo '2==PID='$BASHPID echo '2==PPID='$PPID echo '2==PATH='$PATH echo '2==export=='`export -p` exec -c ./test3// 文件 test3 #!/usr/bin/bash set -e echo '3==PID='$BASHPID echo '3==PPID='$PPID echo '3==PATH='$PATH echo '3==export='`export -p`//执行 $ ./test1 2==PID=28697 2==PPID=28696 2==PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin 2==export==declare -x DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/1000/bus" declare -x HOME="用户主目录" declare -x LANG="en_US.UTF-8" declare -x LC_TERMINAL="iTerm2" declare -x LC_TERMINAL_VERSION="3.3.8" declare -x LESSCLOSE="/usr/bin/lesspipe %s %s" declare -x LESSOPEN="| /usr/bin/lesspipe %s" declare -x LOGNAME="登录用户" declare -x LS_COLORS="rs=0:di=01; 34:ln=01; 36:mh=00:pi=40; 33:so=01; 35:do=01; 35:bd=40; 33; 01:cd=40; 33; 01:or=40; 31; 01:mi=00:su=37; 41:sg=30; 43:ca=30; 41:tw=30; 42:ow=34; 42:st=37; 44:ex=01; 32:*.tar=01; 31:*.tgz=01; 31:*.arc=01; 31:*.arj=01; 31:*.taz=01; 31:*.lha=01; 31:*.lz4=01; 31:*.lzh=01; 31:*.lzma=01; 31:*.tlz=01; 31:*.txz=01; 31:*.tzo=01; 31:*.t7z=01; 31:*.zip=01; 31:*.z=01; 31:*.dz=01; 31:*.gz=01; 31:*.lrz=01; 31:*.lz=01; 31:*.lzo=01; 31:*.xz=01; 31:*.zst=01; 31:*.tzst=01; 31:*.bz2=01; 31:*.bz=01; 31:*.tbz=01; 31:*.tbz2=01; 31:*.tz=01; 31:*.deb=01; 31:*.rpm=01; 31:*.jar=01; 31:*.war=01; 31:*.ear=01; 31:*.sar=01; 31:*.rar=01; 31:*.alz=01; 31:*.ace=01; 31:*.zoo=01; 31:*.cpio=01; 31:*.7z=01; 31:*.rz=01; 31:*.cab=01; 31:*.wim=01; 31:*.swm=01; 31:*.dwm=01; 31:*.esd=01; 31:*.jpg=01; 35:*.jpeg=01; 35:*.mjpg=01; 35:*.mjpeg=01; 35:*.gif=01; 35:*.bmp=01; 35:*.pbm=01; 35:*.pgm=01; 35:*.ppm=01; 35:*.tga=01; 35:*.xbm=01; 35:*.xpm=01; 35:*.tif=01; 35:*.tiff=01; 35:*.png=01; 35:*.svg=01; 35:*.svgz=01; 35:*.mng=01; 35:*.pcx=01; 35:*.mov=01; 35:*.mpg=01; 35:*.mpeg=01; 35:*.m2v=01; 35:*.mkv=01; 35:*.webm=01; 35:*.webp=01; 35:*.ogm=01; 35:*.mp4=01; 35:*.m4v=01; 35:*.mp4v=01; 35:*.vob=01; 35:*.qt=01; 35:*.nuv=01; 35:*.wmv=01; 35:*.asf=01; 35:*.rm=01; 35:*.rmvb=01; 35:*.flc=01; 35:*.avi=01; 35:*.fli=01; 35:*.flv=01; 35:*.gl=01; 35:*.dl=01; 35:*.xcf=01; 35:*.xwd=01; 35:*.yuv=01; 35:*.cgm=01; 35:*.emf=01; 35:*.ogv=01; 35:*.ogx=01; 35:*.aac=00; 36:*.au=00; 36:*.flac=00; 36:*.m4a=00; 36:*.mid=00; 36:*.midi=00; 36:*.mka=00; 36:*.mp3=00; 36:*.mpc=00; 36:*.ogg=00; 36:*.ra=00; 36:*.wav=00; 36:*.oga=00; 36:*.opus=00; 36:*.spx=00; 36:*.xspf=00; 36:" declare -x MOTD_SHOWN="pam" declare -x OLDPWD="用户目录" declare -x PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" declare -x PWD="当前目录名" declare -x SHELL="/bin/bash" declare -x SHLVL="3" declare -x SSH_CLIENT="192.168.0.101 51426 22" declare -x SSH_CONNECTION="192.168.0.101 51426 192.168.0.121 22" declare -x SSH_TTY="/dev/pts/0" declare -x TERM="xterm-256color" declare -x USER="用户名" declare -x XDG_DATA_DIRS="/usr/local/share:/usr/share:/var/lib/snapd/desktop" declare -x XDG_RUNTIME_DIR="/run/user/1000" declare -x XDG_SESSION_CLASS="user" declare -x XDG_SESSION_ID="204" declare -x XDG_SESSION_TYPE="tty" 3==PID=28697 3==PPID=28696 3==PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 3==export=declare -x OLDPWD declare -x PWD="当前目录名" declare -x SHLVL="1"

观察输出
test2test3 的进程id、父进程id相同,后者的环境变量(export -p)可以看做为空(PWD 是当前目录名,SHLVL 是 shell 深度)。
但奇怪的是,test3echo $PATH 居然不是空的,明明在 export -p 的输出中是没有 PATH 的。
查询 test3 输出的 PATH 是什么
  • 猜测由于环境变量为空,继承了某个全局环境变量,在全局环境下搜索
    $ grep -rns /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin / /etc/environment:1:PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" /etc/login.defs:102:ENV_SUPATHPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ^C

  • /etc/environment 只有一行没有多余信息,看 /etc/login.defs 的注释
    # # *REQUIRED*The default PATH settings, for superuser and normal users. //必要:分别为超级用户和普通用户设置默认 PATH # # (they are minimal, add the rest in the shell startup files) ENV_SUPATHPATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin ENV_PATHPATH=/usr/local/bin:/usr/bin:/bin:/usr/local/games:/usr/games

  • 在 bing 上也搜索到一条答案 what is ENV_SUPATH
    https://unix.stackexchange.com/questions/317338/etc-login-defs-env-path-env-supath-vs-path

参考
  • Bash Reference Manual:https://www.gnu.org/software/...
  • /etc/login.defs: ENV_PATH & ENV_SUPATH vs PATH:https://unix.stackexchange.co...

    推荐阅读