【问题标题】:Python invisible environment variable USERNAME without root没有root的Python不可见环境变量USERNAME
【发布时间】:2021-06-15 15:56:41
【问题描述】:

出于安全和方便的目的,我想使用环境变量来存储一些凭据和一些其他信息。我已经把一些放到 /etc/environment 中,源化它并检查这两个变量对 root 用户和普通用户都是可见的:

$ cat /etc/environment
PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin"
MAIL_PASSWORD="pwd"
USERNAME="un"
$ source /etc/environment
$ echo $USERNAME ";" $MAIL_PASSWORD
un ; pwd
$ sudo echo $USERNAME ";" $MAIL_PASSWORD
un ; pwd

然后我启动了 python shell(当我使用脚本并像python3 test.py 一样调用它时,还显示这种行为仍然存在)并尝试获取这个变量:

$ python3
Python 3.8.6 (default, Jan 27 2021, 15:42:20) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print(os.getenv('MAIL_PASSWORD'))
pwd
>>> print(os.getenv('USERNAME'))
None
>>> 

嗯,其中一个肯定没问题,但是另一个隐藏起来了。试图找出这种行为的原因,我尝试了同样的 root 权限:

$ sudo python3
Python 3.8.6 (default, Jan 27 2021, 15:42:20) 
[GCC 10.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> print(os.getenv('MAIL_PASSWORD'))
pwd
>>> print(os.getenv('USERNAME'))
un
>>> 

现在一切正常。

我很困惑,因为这个问题与变量名有关。我尝试将 USERNAME 重命名为 USER 并且成功了,变量 $USER 对于 python 和 shell 都是可见的。所以变量名 USERNAME 有问题,但我在文档中找不到有关它的信息。

谁能解释观察到的结果?当然,我可以忽略它,并使用另一个变量名,但找到解释可能会很有趣。

如果是相关的,我正在运行 ubuntu 20.10,这个问题首先是在 ubuntu 20.04 中发现的。仅测试 Python 3.8 版本。

【问题讨论】:

  • 参见askubuntu.com/questions/866161/… ...尤其是解释 /etc/environment 用途的部分。老实说,我不认为用户名或密码等信息应该进入那里。这与良好的安全性相反。
  • $ sudo echo $USERNAME ";" $MAIL_PASSWORD 无法显示任何内容。无论如何,在运行 sudo 之前都会扩展变量....
  • 它不能解决问题。使用任何其他来源(在本地目录中也尝试过 ~/.bash_profile 和 .env)不会改变行为。之所以选择上述文件,是因为我正在创建一个要使用 cron 运行的脚本,并且它是本地调试时最简单的。在最终版本中不使用 /etc/environment。我只是想知道,为什么 python 对 envvars 的解释取决于它们的名称或其他我不明白的东西。
  • 啊。是的,关于扩展,你是对的,谢谢。用sudo su试过,效果一样(在shell和python shell中都可见)。
  • sudo su <user> echo $USERNAME ";" $MAIL_PASSWORD 也是没用的...您可能想了解 shell 的工作原理以及变量扩展的作用和工作原理,以及单和双之间的区别引号 - 以及何时使用单引号以及它们的作用。您可以尝试sudo sh -c 'echo $USERNAME ";" $MAIL_PASSWORD' 实际上有一个扩展变量的sh 子进程。或sudo -s echo '$USERNAME ; $MAIL_PASSWORD'

标签: python-3.x linux environment-variables python-3.8


【解决方案1】:

谁能解释观察到的结果?

结果可以解释为:

  • 您没有重新启动/重新登录/刷新 PAM 会话。
  • MAIL_PASSWORD 变量在当前 shell 中导出。
  • USERNAME 变量未导出。
 $ python3

您采购了/etc/environemnt。变量USERNAME 未导出。它不会传递给子进程的环境。 python 是一个子进程。所以它没有变量集。但是MAIL_PASSWORD是在父shell中导出的,所以设置了。

$ sudo python3

sudo 打开pam 以运行pam_env 并解析/etc/environemnt。变量由pam_env 导出。因此,这些变量在子进程中是可见的。

出于安全和方便的目的,我想使用环境变量来存储一些凭据和一些其他信息

太棒了!所以,基于意见:

  • 如果您希望您的变量仅在 PAM 会话中可见(在您登录后,使用密码),请将它们放入 /etc/environment/etc/security/pam_env.conf。见man environment。这也将为您工作站上的所有用户导出变量。我说你应该很少或永远不要使用/etc/environment
  • 推荐用于所有 Bourne 兼容登录 shell 的整个工作站:如果您希望您的变量在 shell 登录会话中可见,请将其设置为 /etc/profile,或者如果您的发行版支持,最好将文件添加到 /etc/profile.d。请记住保持与 POSIX sh 兼容的语法。
  • 类似,对于 csh 兼容的 shell,有 /etc/csh.login/etc/profile.d/*.csh
  • 如果您想为您的用户仅登录 shell 设置变量,请使用 ~/.profile。仅限 bash ~/.bash_profile
  • 推荐,对于单用户:为任何新的交互式 bash shell 设置一个变量,只需使用~/.bashrc

【讨论】:

  • 谢谢。现在我知道它是如何工作的了。第一个变量确实是在 ~/.bash_profile 中导出的(具有其他值,但没关系),这就是导致不同结果的原因。重命名为 USER 重新分配了系统环境变量。打算阅读更多关于 shell...
  • USER 由登录设置,参见 hhttps://unix.stackexchange.com/questions/76354/who-sets-user-and-username-environment-variables @edit 。选择一个唯一的前缀,例如 MY_MAIL_PASSWORDMY_USERNAME,这样您的变量就不会干扰其他变量。 USERNAME 看起来像一个过于简单的变量名。
  • 是的,它是为了测试并最终明白,我到底做错了什么。选择唯一名称时,如果不导出,它们都不可见。
猜你喜欢
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-24
  • 2019-07-15
  • 2021-07-11
相关资源
最近更新 更多