有没有办法在Python中检查os.environ的条目是变量还是shell函数?

时间:2013-11-28 06:55:11

标签: python bash shell environment-variables

使用Python中的os模块,我们可以通过dict os.environ轻松访问环境变量。但是,我发现os.environ不仅包含变量,还包含全局定义的shell函数(例如,来自module软件包)。

是否可以从Python中找出os.environ中的给定条目是否实际上是函数而不是变量?请注意,首选与shell无关的解决方案,但我也可以选择适合Bash的解决方案。

3 个答案:

答案 0 :(得分:7)

此功能特定于bash,因此对导出的shell函数的测试需要执行Bash所做的操作。实验和source code显示Bash在启动时通过其值中存在() {前缀将环境变量识别为shell函数 - 如果前缀丢失,或者甚至略有改变,则变量将被处理作为一个普通的数据变量。

因此,等效的Python检查将如下所示:

def is_env_shell_func(name):
    return os.environ[name].startswith('() {')

答案 1 :(得分:3)

我发现可以使用的一种解决方案(但这非常笨拙)如下:

import subprocess

var = 'my_variable_name_i_want_to_check'
p = subprocess.Popen('declare -f ' + var, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.communicate()

if p.returncode == 0:
    print('function')
else:
    print('variable')

答案 2 :(得分:2)

你确定os.environ中有shell函数吗?

{master>}% function test_fn() {
function> echo "Hello";
function> }
{master>}% test_fn
Hello
{master>}% python
Python 2.7.3 (default, Jan  2 2013, 13:56:14) 
[GCC 4.7.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.environ['test_fn']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.7/UserDict.py", line 23, in __getitem__
    raise KeyError(key)
KeyError: 'test_fn'
>>> os.environ.keys()
['SSH_ASKPASS', 'PS_FORMAT', 'GIT_PS1_SHOWDIRTYSTATE', 'GNOME_DESKTOP_SESSION_ID', 'WINDOWPATH', 'LOGNAME', 'USER', 'GNOME_KEYRING_CONTROL', 'HOME', 'PS1', 'DISPLAY', 'PATH', 'LANG', 'TERM', 'SHELL', 'SSH_AGENT_PID', 'XAUTHORITY', 'LANGUAGE', 'GIT_PS1_SHOWSTASHSTATE', 'SHLVL', 'GIT_PS1_SHOWUPSTREAM', 'WINDOWID', 'EDITOR', 'MANPATH', 'GIT_PS1_SHOWCOLORHINTS', 'GPG_AGENT_INFO', 'USERNAME', 'WORKON_HOME', 'COLORTERM', 'WORDCHARS', 'SSH_AUTH_SOCK', 'TMUX', 'GDMSESSION', 'XDG_SESSION_COOKIE', 'LS_OPTIONS', 'DBUS_SESSION_BUS_ADDRESS', '_', 'VIRTUALENVWRAPPER_HOOK_DIR', 'VIRTUALENVWRAPPER_PROJECT_FILENAME', 'DESKTOP_SESSION', 'GIT_PS1_SHOWUNTRACKEDFILES', 'GNOME_KEYRING_PID', 'WINDOW_MANAGER', 'ZBEEP', 'PYTHONSTARTUP', 'OLDPWD', 'SESSION_MANAGER', 'XDG_DATA_DIRS', 'PWD', 'CFLAGS', 'VIRTUALENVWRAPPER_LOG_DIR', 'LS_COLORS', 'TMUX_PANE']
>>>