解決subprocess.Popen在windows下執行命令報的KeyError: 'PATH'問題


最近接到一個使用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"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,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", 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
>>> 

可以發現對應的環境變量中只剩下{'TEST': 'hello world'}了,這時候因為沒有繼承父進程中的環境變量所以PATH變量也就不存在了,所以這時候就會報錯,解決辦法是設置env變量的將PATH變量一起加上就可以了,如果不加上PATH執行一些非shell內建命令時會提示“不是內部或外部命令,也不是可運行的程序 或批處理文件”,這是因為PATH不存在相應的命令也就搜索不到了加上就可以了

>>> pipe=subprocess.Popen(['python','-c',"import os;print(os.environ.get('test'))"],stdout=subprocess.PIPE,stderr=subprocess.STDOUT,env={'test':'hello world','PATH':os.environ.setdefault('PATH')})
>>> print pipe.stdout.read()
hello world
>>> 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM