解決subprocess.Popen在windows下執行命令報的KeyError: 'PATH'問題
阿新 • • 發佈:2020-05-29
最近接到一個使用python寫一個解析yaml檔案,並根據內容配置指定對應的shell來執行(比如bat、powershell、bash、csh、zsh等)命令的功能,於是考慮使用subprocess.Popen模組來實現執行命令相關的功能,subprocess.Popen詳細的引數這裡不細述,自己在測試執行python命令檢視輸出顯示如下錯誤資訊
>>> pipe=subprocess.Popen([‘python‘,‘-c‘,"import os;print(os.environ.get(‘test‘))"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env={‘test‘:‘hello world‘}) >>> print pipe.stdout.read() hello world Error processing line 5 of C:\Python27\lib\site-packages\pywin32.pth: Traceback (most recent call last): File "C:\Python27\lib\site.py",line 152,in addpackage exec line File "<string>",line 1,in <module> File"C:\Python27\lib\os.py",line 425,in __getitem__ return self.data[key.upper()] KeyError: ‘PATH‘ Remainder of file ignored
這時仔細檢視subprocess.Popen詳細env的引數說明
env引數: 如果env不是None,則子程式的環境變數由env的值來設定,而不是預設那樣繼承父程序的環境變數。注意,即使你只在env裡定義了 某一個環境變數的值,也會阻止子程式得到其 他的父程序的環境變數(也就是說,如果env裡只有1項,那麼子程序的環境變數就只有1個了)
發現是設定env環境變數的值之後則子程式不再繼承父程序的環境變量了,這個時候列印子程式裡面對應的環境變數可以發現只有env中指定的相關值了,咱們使用os.environ測試下
>>> pipe=subprocess.Popen([‘python‘,‘-c‘,"import os;print os.environ"],env={‘test‘:‘hello world‘}) >>> print pipe.stdout.read() {‘TEST‘: ‘hello world‘} Error processing line 5 of C:\Python27\lib\site-packages\pywin32.pth: Traceback (most recent call last): File "C:\Python27\lib\site.py",in addpackage exec line File "<string>",in <module> File "C:\Python27\lib\os.py",in __getitem__ return self.data[key.upper()] KeyError: ‘PATH‘ Remainder of file ignored >>>
可以發現對應的環境變數中只剩下{‘TEST‘: ‘hello world‘}了,這時候因為沒有繼承父程序中的環境變數所以PATH變數也就不存在了,所以這時候就會報錯,解決辦法是設定env變數的將PATH變數一起加上就可以了,如果不加上PATH執行一些非shell內建命令時會提示“不是內部或外部命令,也不是可執行的程式 或批處理檔案”,這是因為PATH不存在相應的命令也就搜尋不到了加上就可以了
>>> pipe=subprocess.Popen([‘python‘,env={‘test‘:‘hello world‘,‘PATH‘:os.environ.setdefault(‘PATH‘)}) >>> print pipe.stdout.read() hello world >>>