NixOS環境にPPIDをエクスポートする際の一貫性のない動作

NixOS環境にPPIDをエクスポートする際の一貫性のない動作

PPIDBashは環境変数にエクスポートしようとしました。しかし、私の考えでは、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変数は、親プロセスIDの値を反映する特別なシェル変数(環境変数ではありません)です。値を環境にエクスポートできますが、サブシェルに渡されると、サブシェルは新しいシェル変数を作成し、サブPPIDプロセスPPIDにエクスポートする変数のリストからそれらを削除します。

さまざまなオペレーティングシステムまたはディストリビューション間の動作の違いは、一部のオペレーティングシステムまたはディストリビューションでは、子プロセスがラッパーシェルスクリプトを介して呼び出されますが、他のオペレーティングシステムではそうでないという事実によって説明できます。ラッパースクリプトを使用すると、中間シェルが環境PPIDから削除されますが、最終プロセス(Pythonまたはnvim)が直接実行されても、PPID変数はまだ環境に残ります。

関連情報