将 PPID 导出到 NixOS 上的环境时行为不一致

将 PPID 导出到 NixOS 上的环境时行为不一致

在 bash 中我尝试导出PPID为环境变量。但在我看来,不同 Linux 发行版的结果非常不一致。

在 Ubuntu 18.04 上最多下面的命令“按预期”工作。在 NixOS 上我得到以下行为:

# normally PPID is not part of the environment
env | grep PPID
# --> no output

# exporting for a single command does not work
PPID=foo some-command
# --> bash: PPID: readonly variable

# exporting "works" (it does not print an error)
export PPID
# and the variable seems to be part of the environment
env | grep PPID
# --> PPID=12345
awk 'BEGIN{print ENVIRON["PPID"]; exit}'
# --> 12345
# but some external commands don't see it!
python -c 'import os; print(os.environ.get("PPID"))'
# --> None on NixOS // 12345 on Ubuntu
nvim --headless -u NONE -i NONE -c 'echo $PPID' -c quit
# --> *no output* (on NixOS and Ubuntu)

# using env to export it explicitly, so bash will not complain,
# "works" as good as `export PPID` above, but does not produce 
# the "readonly variable" error message
env PPID=foo awk 'BEGIN{print ENVIRON["PPID"]; exit}'
# -> foo
env PPID=foo python -c 'import os; print(os.environ.get("PPID"))'
# --> None // foo on Ubuntu

如果我将环境变量的名称更改为其他名称(这在 bash 中并不特殊),那么PARENT_PROCESS它在两个发行版和我测试的所有命令上都会按预期工作。

有人能解释一下这是怎么回事吗?


NixOS 上的版本不稳定 ( 21.03pre244045.1179840f9a8 (Okapi)):

  • 重击:GNU bash, version 4.4.23(1)-release (x86_64-unknown-linux-gnu)来自/nix/store/xadrr3l5jvkkm3g3lb2g81j5wz51zqdv-bash-interactive-4.4-p23/bin/bash
  • 库:/nix/store/9df65igwjmf2wbw0gbrrgair6piqjgmi-glibc-2.31/lib/libc-2.31.so

Ubuntu 18.04 上的版本:

  • bash:GNU bash, version 4.4.20(1)-release (x86_64-pc-linux-gnu)来自包bash版本4.4.18-2ubuntu1.2
  • libc:2.27(来自软件包libc6版本)2.27-3ubuntu1.2

答案1

PPID变量是一个特殊的 shell 变量(不是环境变量),它反映了父进程 id 的值。该值可以导出到环境中,但如果将其传递到子 shell,则子 shell 会创建一个新的PPIDshell 变量,并PPID从要导出到子进程的变量列表中删除。

不同操作系统或发行版之间的行为差​​异可以解释为,在某些操作系统或发行版中,子进程是通过包装器 shell 脚本调用的,而在其他操作系统或发行版中则不是。如果使用包装器脚本,则中间 shellPPID将从环境中删除,但如果直接执行最终进程(Python 或 nvim),则PPID变量仍然在环境中。

相关内容