2014-10-30 22 views
16

Tôi gặp sự cố với việc đặt biến môi trường khi gọi đến subprocess.Popen. Biến môi trường dường như không được thiết lập. Bất kỳ đề xuất về cách thiết lập đúng các biến môi trường cho một cuộc gọi commandline Python?Python: Xuất các biến môi trường trong subprocess.Popen (..)

Mục tiêu của tôi là để chạy một kịch bản có sử dụng một biến môi trường được xác định từ mã Python tôi:

d = dict(os.environ) 
d["TEST_VARIABLE"] = str(1234) 
subprocess.Popen('/usr/bin/mybinary', env=d).wait() 

nhưng kịch bản phản ứng như thể biến chưa bao giờ được thiết lập

Đây là nỗ lực của tôi để kiểm tra, sử dụng thông dịch viên tương tác của Python:

d = dict(os.environ) 
d["TEST_VARIABLE"] = str(1234) 
subprocess.Popen(['/bin/echo', '$TEST_VARIABLE'], env=d).wait() 

và đầu ra là:

"$TEST_VARIABLE" 
0 

Tôi nghĩ env=d nên đặt môi trường cho quy trình con, nhưng có vẻ như không. Bất kỳ đề xuất nào về cách khắc phục vấn đề này?

Trả lời

23

Việc thay thế các biến môi trường trên dòng lệnh được thực hiện bởi vỏ, không phải bởi/bin/echo. Vì vậy, bạn cần phải chạy lệnh trong một vỏ để có được sự thay thế:

In [22]: subprocess.Popen('/bin/echo $TEST_VARIABLE', shell=True, env=d).wait() 
1234 
Out[22]: 0 

Điều đó không có nghĩa là các biến môi trường không được thiết lập khi shell=False, tuy nhiên. Ngay cả khi không có shell=True, tệp thực thi không thấy các biến môi trường được đặt bởi tham số env. Ví dụ, date bị ảnh hưởng bởi biến TZ môi trường:

In [23]: subprocess.Popen(["date"], env={'TZ': 'America/New_York'}).wait() 
Wed Oct 29 22:05:52 EDT 2014 
Out[23]: 0 

In [24]: subprocess.Popen(["date"], env={'TZ': 'Asia/Taipei'}).wait() 
Thu Oct 30 10:06:05 CST 2014 
Out[24]: 0 
2

Bạn nên sử dụng os.environ.copy() để làm cho nó hoạt động. Nó tạo ra một bản sao của toàn bộ từ điển môi trường mà bạn có thể sửa đổi trước khi chuyển nó vào tiến trình con, mà không sửa đổi môi trường quy trình hiện tại.

hãy có một cái nhìn [ở đây]: 1

+1

Vấn đề không phải là môi trường nhưng sự thay thế, như được giải thích bởi câu trả lời được chấp nhận. –

+0

Đúng, nhưng tiêu đề của bài đăng "Xuất", vì vậy điều này rất hữu ích. – gerardw

2

Đối với Python 3.5 và mới hơn, bạn có thể sử dụng unpacking generalizations, ví dụ:

env = { 
    **os.environ, 
    "TEST_VARIABLE": str(1234), 
} 
subprocess.Popen('/usr/bin/mybinary', env=env).wait() 
Các vấn đề liên quan