Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中是否有方法检查os.environ的条目是变量还是shell函数?_Python_Bash_Shell_Environment Variables - Fatal编程技术网

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

Python中是否有方法检查os.environ的条目是变量还是shell函数?,python,bash,shell,environment-variables,Python,Bash,Shell,Environment Variables,使用Python中的os模块,我们可以通过dictos.environ轻松访问环境变量。但是,我发现,os.environ不仅包含变量,还包含全局定义的shell函数(例如来自模块软件包) 从Python内部是否有可能发现os.environ中的给定条目实际上是函数而不是变量?请注意,与shell无关的解决方案是首选的,但我也可以选择特定于Bash的解决方案。您确定os.environ中有shell函数吗 {master>}% function test_fn() { function&g

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


从Python内部是否有可能发现
os.environ
中的给定条目实际上是函数而不是变量?请注意,与shell无关的解决方案是首选的,但我也可以选择特定于Bash的解决方案。

您确定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']
>>> 
{master>}%功能测试{
函数>回显“你好”;
函数>}
{master>}%测试\u fn
你好
{master>}%python
Python 2.7.3(默认值,2013年1月2日,13:56:14)
[GCC 4.7.2]关于linux2
有关详细信息,请键入“帮助”、“版权”、“信用证”或“许可证”。
>>>导入操作系统
>>>操作系统环境['test_fn']
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
文件“/usr/lib/python2.7/UserDict.py”,第23行,在__
升起钥匙错误(钥匙)
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'、'OLORHINTS、GPG_代理信息、用户名、WORKON_HOME、COLORTERM、WORDCHARS、SSH_AUTH_SOCK、TMUX、GDMSESSION、XDG_会话COOKIE、LS_选项、DBUS_会话_总线地址’、’、’、‘VirtualNVrapper_HOOK_DIR’、‘VirtualNVrapper_项目_文件名’、‘桌面_会话’、‘GIT_PS1_显示未跟踪文件’、‘GNOME_密钥环’、‘窗口管理器’、‘Z“嘟嘟声”、“PYTHONSTARTUP”、“OLDPWD”、“会话管理器”、“XDG\U数据目录”、“PWD”、“CFLAGS”、“虚拟说唱者日志目录”、“LS\U颜色”、“TMUX窗格”]
>>> 

我发现一个可行的解决方案(但这是可笑的笨拙)是:

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')

这个特性是特定于bash的,因此对导出的shell函数的测试需要执行bash所做的操作。实验表明,Bash通过在其值中存在
(){
前缀,在启动时将环境变量识别为shell函数-如果前缀缺失,甚至略有更改,则将该变量视为普通数据变量

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

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

是python函数还是bash shell函数?您可以检查python变量,看看它是否可以按此处所述调用:但我感兴趣的是如何将shell函数添加到
os.environ
。这对我来说似乎很奇怪。如下所示,如果您使用
export-f fn
declare-fx fn
导出shell函数,那么函数
fn
将在
os.environ
中结束@VooDooNOFX:bash shell函数是我试图弄明白的。@strustmaster:
export tt='()aw,dayum!;echo$tt
留给我的是
()啊,天啊!
,所以在这种情况下,我们会得到一个假阳性。因为这是一个脚本,将部署在非常异构的系统上,我不能指望没有任何变量内容以
()
。是的,您需要在调用子进程之前执行:
export-f test\u fn
。是的,您也可以使用
declare-fx test\u fn
。同样,我认为对于以
()开头的任何变量,这将返回
True
{
,不仅仅是函数。@MichaelSchlottke这是一个功能,因为这正是识别这些变量的方法。我现在修改了答案,提到了这一点。对不起,我不明白……如果我创建一个变量为
导出非函数='(){wololo}'并运行
declare-f not_a_函数
,它通过返回代码
1`告诉我们,
not_a_函数
实际上不是一个函数。但可能我误解了您的意思。@Michaelschlotke我在Bash 4.2.45中得到的是在启动子shell时为not_a_函数导入函数定义时出现了
错误,所以Bash显然在尝试定义函数。如果您通过在右大括号之前包含一个换行符来修复定义,使其工作,那么定义测试并工作得很好。您能发布用于触发所述行为的代码行吗?我无法用Bash 3.2或4.1重现它。