在 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 会创建一个新的PPID
shell 变量,并PPID
从要导出到子进程的变量列表中删除。
不同操作系统或发行版之间的行为差异可以解释为,在某些操作系统或发行版中,子进程是通过包装器 shell 脚本调用的,而在其他操作系统或发行版中则不是。如果使用包装器脚本,则中间 shellPPID
将从环境中删除,但如果直接执行最终进程(Python 或 nvim),则PPID
变量仍然在环境中。