从Python启动配置的cmd

时间:2013-04-11 10:50:51

标签: python windows process exec

我在 Windows 。我正在尝试编写一个Python 2.x脚本(让我们称之为setup.py),这将启用以下场景:

  1. 用户运行cmd以打开控制台窗口
  2. 在该控制台窗口中,用户运行setup.py
  3. 用户发现自己位于同一个控制台窗口中,但现在运行的cmd已将其环境(环境变量)修改为setup.py
  4. setup.py通过添加值FOO的新环境变量foo以及预先添加PATH内容来修改环境。

    在Linux上,我只需使用os.exec*e将shell进程替换为配置了环境的shell。

    我在Windows上尝试了相同的方法(例如os.exec*e(os.environ['ComSpec'])),但它不起作用,新执行的cmd的环境如下:

    • set投放不会列出FOO,也不会对PATH显示效果。但是,正在运行set FOO会显示FOO=fooecho %FOO%回显foo

    • 正在运行set PATHecho %PATH%会显示已修改的PATH变量。运行set pathecho %path%会显示值而不修改(即使env.vars在Windows上通常不区分大小写)。

    • 如果我输入exit,那么conole会在某些不接受输入的状态下挂起,直到我点击Ctrl+C。之后,它显然会返回最初称为cmd的{​​{1}}。

    很明显,setup.py在Windows上不适用于这种情况。有没有不同的方法来实现我想要的?是否有os.exec*e标志的组合可以让我退出调用的Python进程并离开被调用的cmd runnig,理想情况是在同一个控制台中?或者通过subprocess.Popen()帮助访问CreateProcess

    如果有必要,我会决定启动一个新的控制台窗口并关闭旧的控制台窗口,但是我确实无法承受旧的控制台窗口挂在冻结状态,等待新创建的窗口关闭。

1 个答案:

答案 0 :(得分:2)

如果除了脚本之外使用Windows批处理文件是可以接受的,那么有一个更简单的解决方案,因为批处理文件在调用过程中运行,因此可以修改其环境。

给定文件setup.bat,看起来像这样......

@echo off
for /f "tokens=*" %%a in ('python setup.py') do %%a

...和文件setup.py看起来像这样......

import os
print 'set FOO=foo'
print 'set PATH=%s;%s' % ('C:\\my_path_dir', os.environ['PATH'])

...并假设PATH中有python.exe,然后从命令行调用setup.bat将在调用进程中设置环境变量,同时仍然允许你创建setup.py }脚本尽可能复杂,只要它将要执行的命令打印到stdout。

根据评论进行更新

如果setup.py有多种操作模式,则可以使setup.bat成为通用包装器。假设setup.bat看起来像这样......

@echo off
if "%1" == "setenv" (
    for /f "tokens=*" %%a in ('python setup.py %1') do %%a
) else (
    python setup.py %*
)

...... setup.py看起来像这样......

import sys
import os

if len(sys.argv) > 1 and sys.argv[1] == 'setenv':
    print 'set FOO=foo'
    print 'set PATH=%s;%s' % ('C:\\my_path_dir', os.environ['PATH'])
else:
    print "I'm gonna do something else with argv=%r" % sys.argv

......那还不够吗?