[英]How do I tell POpen to use/set certain environment variables?
我正在使用Python 3.7和Django。 我用下面的命令運行我通常會在外殼中運行的命令...
out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE)
t = out.communicate()[0], out.returncode
他死於錯誤
b'env: node: No such file or directory\n'
我試圖找出的是如何讓我的Python環境訪問我可以訪問的普通環境變量,或者找到一種在運行Python命令之前設置它們的方法。 通常,當我自己檢查時,很容易找到“節點”
davea$ which node
/usr/local/bin/node
但是我不知道如何告訴Python使用我可以訪問的相同PATH。
如果我們參考Popen的文檔 ,我們可以看到三個相關的參數:
cwd
str
或cwd
path
的對象,即當前工作目錄 env
映射(比如說dict
),這就是傳遞給調用程序的環境映射 shell
標志,是否將程序包裝在shell中 讓我們回顧每個解決方案。
如果負擔得起,只需使用cwd="where is node"
,例如,如果node
在/usr/local/bin
,則可以僅使用cwd=/usr/local/bin
或cwd=os.path.join(USR_LOCAL, 'bin')
例如。 但是,所有內容都將在此文件夾中創建,而這可能不是您想要的 (日志,當前工作目錄上的假設)。
現在,針對環境:
如果env不為None,則它必須是為新進程定義環境變量的映射。 這些被用來代替繼承當前進程環境的默認行為。 它直接傳遞給Popen。
您可以通過os.environ
復制當前環境,然后在PATH
添加如下內容:
new_env = os.environ.copy()
new_env['PATH'] = '{}:/usr/local/bin'.format(new_env['PATH'])
然后通過此new_env
映射,您就可以了!
如果您真的想依靠shell,可以,但是這里是平台詳細信息:
在shell = True的POSIX上,shell默認為/ bin / sh。 如果args是字符串,則該字符串指定要通過外殼執行的命令。 這意味着字符串的格式必須與在shell提示符下鍵入時的格式完全相同。 例如,這包括在文件名中使用引號或反斜杠轉義。 如果args是序列,則第一項指定命令字符串,任何其他項都將被視為shell本身的其他參數。 也就是說,Popen等效於:
Popen(['/bin/sh', '-c', args[0], args[1], ...])
在shell = True的Windows上,COMSPEC環境變量指定默認的Shell。 在Windows上唯一需要指定shell = True的時間是將要執行的命令內置到shell中(例如dir或copy)。 您不需要shell = True即可運行批處理文件或基於控制台的可執行文件。
您可以使用類似PATH=whatever
類的PATH=whatever
並直接使用整個shell-fu,但需要注意的是: 安全注意事項。
只需在調用Python進程之前重新定義PATH。 如果您使用的是Django,則可以使用:
在這兩種情況下,您要做的就是重新定義父進程的環境,對於Gunicorn這樣的生產級服務器,這是可能的,並且有文檔可以做到這一點。 對於開發服務器,請在您自己的外殼程序級別上執行此操作(但請注意!您可能必須記錄這種行為,或者告訴任何使用您的軟件的人,您認為node
在…通常是公平的路徑中)。
os.environ.copy()
最適合您要尋找的東西。
import subprocess, os
my_env = os.environ.copy()
out = Popen([settings.SELENIUM_RUNNER_CMD, file_path], stderr=STDOUT, stdout=PIPE, env=my_env)
t = out.communicate()[0], out.returncode
就是這樣!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.