如何在Python中从环境变量设置字符串?

时间:2017-06-11 02:23:19

标签: 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视为一串字节的方法是什么?

4 个答案:

答案 0 :(得分:5)

还有一个选项,只需在Bash中将其设置为二进制数据即可。这使用ANSI string quoting

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

答案 1 :(得分:3)

你可以' unescape' Python中的字节:

let currentDate = Date()
let dateFormatter = DateFormatter()
var timer = Timer()
let userCalendar = Calendar.current

let requestedComponent: Set<Calendar.Component> = [.day,.hour,.minute,.second]


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(printTime), userInfo: nil, repeats: true)
    timer.fire()



}

func printTime()
{
    dateFormatter.dateFormat = "dd/MM/yy hh:mm:ss"
    let startTime = Date()
     let endTime = dateFormatter.date(from: "11/03/18 10:00:00")

    let time = userCalendar.dateComponents(requestedComponent, from: startTime, to: endTime!)

    if time.day! == 0 && time.hour! == 0 && time.minute! == 0 && time.second! == 0 {timer.invalidate()}

    dayLabel.text = "\(time.day!)"
    hourLabel.text = "\(time.hour!)"
    minuteLabel.text = "\(time.minute!)"
    secondLabel.text = "\(time.second!)"
}

答案 2 :(得分:1)

根据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将其解码回原始值。

答案 3 :(得分:0)

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

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