繁体   English   中英

如何从 Python 中的环境变量设置一串字节?

[英]How do you set a string of bytes from an environment variable in Python?

假设你有一个通过os.urandom(24)生成的字节串,

b'\x1b\xba\x94(\xae\xd0\xb2\xa6\xf2f\xf6\x1fI\xed\xbao$\xc6D\x08\xba\x81\x96v'

你想把它存储在一个环境变量中,

export FOO='\x1b\xba\x94(\xae\xd0\xb2\xa6\xf2f\xf6\x1fI\xed\xbao$\xc6D\x08\xba\x81\x96v'

并使用os.environ从 Python 程序中检索值。

foo = os.environ['FOO']

问题是,在这里, foo具有字符串文字值'\\\\x1b\\\\xba\\\\x94...而不是字节序列b'\\x1b\\xba\\x94...

要使用的正确export值是什么,或者使用os.environFOO视为一串字节的方法是什么?

最简单的选择是在 Bash 中简单地将其设置为二进制数据。 这使用ANSI 字符串引用并避免在 Python 端进行任何类型的转换。

export FOO=$'\x1b\xba\x94(\xae\xd0\xb2\xa6\xf2f\xf6\x1fI\xed\xbao$\xc6D\x08\xba\x81\x96v'

您可以使用以下命令在 Python 中“取消转义”您的字节:

import os
import sys

if sys.version_info[0] < 3:  # sadly, it's done differently in Python 2.x vs 3.x
    foo = os.environ["FOO"].decode('string_escape')  # since already in bytes...
else:
    foo = bytes(os.environ["FOO"], "utf-8").decode('unicode_escape')

有了 zwer 的回答,我尝试了以下操作

首先来自 bash(这与 ybakos 给出的二进制文字相同)

export FOO='\x1b\xba\x94(\xae\xd0\xb2\xa6\xf2f\xf6\x1fI\xed\xbao$\xc6D\x08\xba\x81\x96v'

然后我启动了python shell(我有python 3.5.2)

>>> import os
>>> # ybakos's original binary literal
>>> foo =  b'\x1b\xba\x94(\xae\xd0\xb2\xa6\xf2f\xf6\x1fI\xed\xbao$\xc6D\x08\xba\x81\x96v'
>>> # ewer's python 3.x solution
>>> FOO = bytes(os.environ["FOO"], "utf-8").decode('unicode_escape')
>>> foo == FOO
False
>>> ^D

foo == FOO 的最后一行应该返回 true,因此该解决方案似乎无法正常工作。

我注意到有一个os.envirnb字典,但我无法弄清楚将环境变量设置为二进制文字,所以我尝试了以下使用 base64 编码的替代方法来获取二进制文字的 ASCII 版本。

首次启动python shell

>>> import os
>>> import base64
>>> foo = os.urandom(24)
>>> foo
b'{\xd9q\x90\x8b\xba\xecv\xb3\xcb\x1e<\xd7\xba\xf1\xb4\x99\xf056\x90U\x16\xae'
>>> foo_base64 = base64.b64encode(foo)
>>> foo_base64
b'e9lxkIu67Hazyx4817rxtJnwNTaQVRau'
>>> ^D

然后在bash shell中

export FOO_BASE64='e9lxkIu67Hazyx4817rxtJnwNTaQVRau'

然后回到python shell

>>> import os
>>> import base64
>>> # the original binary value from the first python shell session
>>> foo = b'{\xd9q\x90\x8b\xba\xecv\xb3\xcb\x1e<\xd7\xba\xf1\xb4\x99\xf056\x90U\x16\xae'
>>> dec_foo = base64.b64decode(bytes(os.environ.get('FOO_BASE64'), "utf-8"))
>>> # the values match!
>>> foo == dec_foo
True
>>> ^D

最后一行显示2个结果是一样的!!

我们正在做的是首先从 os.urandom() 获取一个二进制值并对其进行 Base64 编码。 然后我们使用 Base64 编码的值来设置环境变量。 注意: base64.b64encode()返回一个二进制值,但它只包含可打印的 ASCII 字符。

然后在我们的程序中,我们从环境变量中读取 Base64 编码字符串值,将字符串转换为二进制形式,最后 Base64 将其解码回其原始值。

这比您想象的要容易。 只需将其存储为平面字符串并对该字符串进行编码。 它将返回一个二进制数据。 例如:

foo = '{\xd9q\x90\x8b\xba\xecv\xb3\xcb\x1e<\xd7\xba\xf1\xb4\x99\xf056\x90U\x16\xae'
B_FOO = str.encode(foo)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM