【问题标题】:Protect against null environment variables when using os.path.expandvars使用 os.path.expandvars 时防止空环境变量
【发布时间】:2016-10-14 12:27:09
【问题描述】:

如何防止 Python 的 os.path.expandvars() 处理 null/unset 环境变量?

来自os.path

格式错误的变量名和对不存在变量的引用保持不变。

>>> os.path.expandvars('$HOME/stuff')
'/home/dennis/stuff'
>>> os.path.expandvars('foo/$UNSET/bar')
'foo/$UNSET/bar'

我可以将这一步与其他路径处理(expanduser()realpath(),normpath() 等)分开执行,而不是将它们全部链接在一起并检查结果是否不变,但是当存在没有变量存在 - 所以我还必须解析字符串以查看它是否有任何变量。我担心这可能不够健壮。

使用结果创建文件时会出现问题。我最终得到一个文件,其中变量名作为文件名的文字部分。我想改为拒绝输入但有异常。

【问题讨论】:

  • 您的应用程序是否有办法知道需要哪些环境变量?它可以先检查它们,并将任何丢失的设置为空字符串。

标签: python path environment-variables


【解决方案1】:

您可以使用string.Template,它使用类似的美元符号语法来插值变量,但如果某些东西不存在而不是保留它,则会引发KeyError

import os
from string import Template
print(Template('$HOME/stuff').substitute(os.environ))

【讨论】:

  • 这太棒了!它甚至支持 shell 花括号 (${HOME})。它不支持 Windows 样式的变量 (%VAR%),但看起来您可以对其进行子类化以支持它。
【解决方案2】:

扩展至Jason's:

def expand_user_vars(s, variants='$%s ${%s} %%%s%%'):
    '''Return a string expanded for both leading "~/" or "~username/" and
    environment variables in the forms given by variants.


    >>> s = "~roland/.local/%XYZ%$XYZ${XYZ}"
    >>> expand_user_vars(s)
    '/home/roland/.local/'
    >>> s = "$HOME/.local/%XYZ%$XYZ${XYZ}"
    >>> expand_user_vars(s)
    '/home/roland/.local/'
    >>> s = "$EDITOR"
    >>> 'EDITOR' not in expand_user_vars(s)
    True

    '''
    s = os.path.expanduser(s)
    #python2 does not have KeyError in str(e)
    remx = re.compile(r"(?:KeyError:)?\s*'(\w+)'")
    while True:
        try:
            s = string.Template(s).substitute(os.environ)
            break
        except KeyError as e:
            reme = str(e)
            remxo = remx.match(reme)
            if remxo:
                g1 = remxo.group(1)
                for v in variants.split():
                    s = s.replace(v%g1,'')
                continue
    return s

否则,echo 存在于 Linux、MacOS 和 Windows 上。 将以下示例替换为 ...'echo '+s...:

import subprocess
netrc_file = subprocess.check_output('echo ${NETRC:-~/.netrc}',shell=True)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多