49

有没有一种简单的方法可以在 Windows/Linux/OS X 上运行 Python 脚本?

在后两者上subprocess.Popen("/the/script.py")有效,但在 Windows 上出现以下错误:

Traceback (most recent call last):
  File "test_functional.py", line 91, in test_functional
    log = tvnamerifiy(tmp)
  File "test_functional.py", line 49, in tvnamerifiy
    stdout = PIPE
  File "C:\Python26\lib\subprocess.py", line 595, in __init__
    errread, errwrite)
  File "C:\Python26\lib\subprocess.py", line 804, in _execute_child
    startupinfo)
WindowsError: [Error 193] %1 is not a valid Win32 application

蒙库特的评论:用例不清楚。为什么要使用 subprocess 来运行 python 脚本?是否有什么东西阻止您导入脚本并调用必要的函数?

我正在编写一个快速脚本来测试 Python 命令行工具的整体功能(在各种平台上进行测试)。基本上它必须在一个临时文件夹中创建一堆文件,在这个文件夹上运行脚本并检查文件是否被正确重命名。

我本可以导入脚本并调用该函数,但由于它依赖sys.argv并使用sys.exit(),我需要执行类似..

import sys
import tvnamer
sys.argv.append("-b", "/the/folder")
try:
    tvnamer.main()
except BaseException, errormsg:
    print type(errormsg)

另外,我想捕获 stdout 和 stderr 以进行调试,以防出现问题。

当然,更好的方法是以更可单元测试的方式编写脚本,但脚本基本上是“完成”的,我正在做最后一批测试,然后再发布“1.0”版本(之后我要去进行重写/重组,这将更加整洁和可测试)

基本上,在找到sys.executable变量后,将脚本作为一个进程简单地运行要容易得多。我会把它写成一个 shell 脚本,但这不会是跨平台的。最终脚本可以在这里找到

4

8 回答 8

70

刚刚找到sys.executable- 当前 Python 可执行文件的完整路径,可用于运行脚本(而不是依赖 shbang,这显然不适用于 Windows)

import sys
import subprocess

theproc = subprocess.Popen([sys.executable, "myscript.py"])
theproc.communicate()
于 2009-05-26T21:26:10.983 回答
25

这个怎么样:

import sys
import subprocess

theproc = subprocess.Popen("myscript.py", shell = True)
theproc.communicate()                   # ^^^^^^^^^^^^

这告诉subprocess使用 OS shell 打开您的脚本,并适用于您可以在 cmd.exe 中运行的任何内容。

此外,这将在 PATH 中搜索“myscript.py”——这可能是可取的。

于 2009-06-24T01:48:17.893 回答
7

subprocess.Popen(cmd, ..., shell=True)的,它就像一个魅力。在 Windows 上,.py文件扩展名被识别,因此调用 Python 来处理它(在 *NIX 上只是通常的 shebang)。路径环境控制事物是否被看到。所以第一个 arg toPopen只是脚本的名称

subprocess.Popen(['myscript.py', 'arg1', ...], ..., shell=True)
于 2011-06-13T10:15:57.697 回答
5

看起来 Windows 尝试使用自己的 EXE 框架运行脚本,而不是像这样调用它

python /the/script.py

尝试,

subprocess.Popen(["python", "/the/script.py"])

编辑:“python”需要在你的路径上。

于 2009-05-26T21:29:03.070 回答
3

例如,要使用命令提示符或 BATCH 文件执行以下操作,我们可以使用它:

C:\Python27\python.exe "C:\Program files(x86)\dev_appserver.py" --host 0.0.0.0 --post 8080 "C:\blabla\"

与 Python 一样,我们可以这样做:

subprocess.Popen(['C:/Python27/python.exe', 'C:\\Program files(x86)\\dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:\\blabla'], shell=True)

或者

subprocess.Popen(['C:/Python27/python.exe', 'C:/Program files(x86)/dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:/blabla'], shell=True)
于 2014-07-15T07:40:06.250 回答
2

您正在使用依赖于平台的路径名分隔符。Windows 使用“\”,Unix 使用“/”。

于 2009-05-27T08:08:52.547 回答
1

当您在子进程中的 windows 上运行 python 脚本时,您应该在脚本名称前使用 python。尝试:

process = subprocess.Popen("python /the/script.py")
于 2009-05-26T21:26:41.250 回答
0

补充信息:值得注意的是,shell=True如果您使用 dos shell 命令,则文档说明您需要使用dir

没有它你会得到这样的东西。

>>> import subprocess
>>> subprocess.run(['dir'])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\foo\AppData\Local\Programs\Python\Python38\lib\subprocess.py", line 489, in run
    with Popen(*popenargs, **kwargs) as process:
  File "C:\Users\foo\AppData\Local\Programs\Python\Python38\lib\subprocess.py", line 854, in __ini
t__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "C:\Users\foo\AppData\Local\Programs\Python\Python38\lib\subprocess.py", line 1307, in _exe
cute_child
    hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
FileNotFoundError: [WinError 2] The system cannot find the file specified
>>> subprocess.run(['dir'], shell=True)
 Volume in drive J is garbage
 Volume Serial Number is 5EE7-B084

您也可以对最近添加的 args 使用类似路径的对象。

from pathlib import Path 
subprocess.run(Path('c:/proj/myfile.bat'))

另外值得注意的是,有一整套特定于 Windows 的控件,可让您控制进程的生成方式,哪些并发操作可以使用。

所以在windows上控制子进程并不像posix风格那么简单。

于 2021-11-19T09:23:04.080 回答