【问题标题】:Python Vs C - Handling environment variable in WindowsPython Vs C - 在 Windows 中处理环境变量
【发布时间】:2009-10-15 12:48:29
【问题描述】:

我看到 Windows 中 C 代码和 python 代码之间的输出不同,试图获得相同的功能。 c 代码(类似于 unix shell 脚本)在“test.bat.output”中显示 TEST1 环境变量,其值为空字符串,而 python 代码删除此环境变量。

有没有办法让Python在环境表为空时不要删除环境变量?

C

#include <windows.h>

main()
{

  DWORD dwRet;
  char pszOldVal[1024] = "abc";

  if(! SetEnvironmentVariable("TEST1", ""))  
    puts("Error\n");

  // _putenv("TEST1=");

  // GetEnvironmentVariable("TEST1", pszOldVal, dwRet);
  system("cmd /c test.bat >test.bat.output");
}

Python

import os
os.environ['TEST1'] = ""
os.environ['TEST2'] = "karthik"
os.system("cmd /c test.bat > test.bat.output.python")

-卡提克

【问题讨论】:

  • 请学习使用 Stack Overflow 代码格式化。
  • 嗯。 S.Lott,你踩了我的编辑……编辑系统有点像那样。 :( 无论如何,是的。代码格式很重要。
  • 出于好奇,具有空值的环境变量所需的语义是什么?
  • 我一定会遵守代码格式化规则。感谢洛特指出。如果我没记错的话,在 Windows 中将变量设置为空字符串等同于 Linux 中的“未设置”。但是这种行为在 Windows 下的 C 和 python 中至少应该是一致的。
  • 我回复了您对我的回答的评论。您可能会发现它很有帮助。

标签: python c environment-variables


【解决方案1】:

Windows 和“大多数其他人”(从 Unix 派生或启发的操作系统)之间的跨平台兼容性通常很难获得,尤其是在不可避免地出现的无数极端情况下(例如,在这个问题中,“是否设置清空环境变量意味着取消设置”)。有时,直接访问 Windows 特定功能比尝试扩展“跨平台”功能更容易。

虽然从 Python 访问特定于 Windows 的功能的传统方法是 win32all 扩展包,但在最近的 Python 版本中,ctypes 标准库模块提供了一种替代方法,其优点是无需安装 C 编码扩展。 jaraco.windows 是一个有趣的项目,它是在 ctypes 之上的一组纯 Python 代码,使 Windows 操作更容易和更流畅。例如,如果您使用环境和/或注册表,environ.py 模块提供了一组很好的函数和类,它们比底层ctypes 访问的裸 win32 API(例如, 在出现错误时获取带有可读错误消息的异常,而不必检查返回码 &c)。

【讨论】:

【解决方案2】:

这是一个可能的答案。我没有方便测试的 Windows 系统,所以我真的不知道这段代码会做什么,但如果你这样做会发生什么:

import os, subprocess
myenv = {}
myenv.update(os.environ)
myenv['TEST1'] = ""
myenv['TEST2'] = "karthik"
subprocess.Popen(('cmd', '/c', 'test.bat'), stdout=file("test.bat.output.python", 'w'),
                 env=myenv).wait()

在我看来,您可能会遇到某种 Python 错误。特别是如果我刚刚给出的代码有效。

此外,在 Unix 下测试您的代码确实有效。环境以一个空的环境变量结束。

【讨论】:

  • 您的建议是获取环境副本并将其用于子流程工作。 C 代码在内部也能以同样的方式工作吗?
  • 我关于它为什么起作用的理论是,os.environ 变量使用的 API 和子进程使用的 API 之间存在差异。我的猜测是 os.environ 使用的 API 是针对那些期望 setenv 在设置为空时删除环境变量的旧程序。
【解决方案3】:

是的,没有将空值放入环境中,但有趣的是从 win32api 或 ctypes 模块调用 SetEnvironmentVariable 与 os.environ 具有相同的效果,尽管 win32api.SetEnvironmentVariable 将调用与 C 中相同的函数。

那么你确定你在 C 代码中得到了不同的结果吗?

import win32api
import os
win32api.SetEnvironmentVariable("TEST1", "")
# or 
# import ctypes
# ctypes.windll.kernel32.SetEnvironmentVariable("TEST1", "")
os.system("echo %TEST1%")

【讨论】:

  • 我可以很容易地看到putenvSetEnvironmentVariable 在Windows 下具有完全不同的语义。
  • 但至少从 python 调用 SetEnvironmentVariable 与 os.environ 或 putenv 具有相同的效果
  • 我没有 win32api 或 ctypes 模块可以在我的 python 安装中立即尝试。但是我所说的关于 C 代码是真的。你能检查一下吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-29
  • 2019-04-02
  • 1970-01-01
相关资源
最近更新 更多