【问题标题】:Why is Python's subprocess' popen so different between unix and windows?为什么 Python 的 subprocess' popen 在 unix 和 windows 之间如此不同?
【发布时间】:2016-01-19 21:56:31
【问题描述】:

我正在尝试用 Python 编写跨平台代码。代码应该生成新的 shell 并运行代码。

这让我看到了 Python 的 subprocess 工具,尤其是它的 Popen 部分。所以我通读了这个类的文档Popen doc,发现太多“if on Unix/if on Windows”语句。不是很跨平台,除非我误解了文档。

发生了什么事?我明白这两个操作系统是不同的,但真的,有没有办法写一个通用的接口?我的意思是,同样的论点“windows is different than unix”可以应用于os、system等,它们看起来都是100%跨平台的。

【问题讨论】:

    标签: python windows unix cross-platform popen


    【解决方案1】:

    问题在于,进程管理是操作系统中根深蒂固的东西,不仅在实现上存在很大差异,甚至在基本功能上也存在很大差异。 实际上,在例如 os 类中抽象代码通常相当容易。两个 C 库,无论是 *nix 还是 Windows,都将读取文件实现为 I/O 流,因此您甚至可以编写在 Windows 和 *nix 中工作相同的相当低级的文件操作函数。

    但过程差异很大。例如,在 *nix 中,进程都是分层的,每个进程都有一个父进程,所有进程都返回到在 PID 1 下运行的 init 系统。通过分叉自己创建一个新进程,检查它是父进程还是子进程,然后相应地继续. 在 Windows 中,进程是严格非分层的,由 CreateProcess () 系统调用创建,您需要特殊权限。 还有很多不同之处,这只是两个示例,但我希望它表明实现一个独立于平台的流程库是一项非常艰巨的任务。

    【讨论】:

    • +1。除此之外,Windows 和 Linux 之间最重要的区别(在为进程管理实现库 API 方面)可能是参数传递给子进程的方式。 Windows 传递代表整个命令行的单个字符串,而 Linux 传递代表单个参数的字符串数组。这听起来可能没什么大不了的,但如果任何参数包含特殊字符,就可以了。程序员经常被这个所吸引。
    • 调用CreateProcess 不需要特殊权限,除非您正在谈论运行需要提升的进程(就完整性级别和访问令牌中启用的组而言)。 appinfo 服务提供对提升的访问令牌的访问。通常,您会使用带有“runas”动词的ShellExecute[Ex] 来访问此服务。 Python 的标准库通过os.startfile 对此只有极少的支持。如果程序显示需要提升,您可以使用Popen 和shell=True。否则需要 ctypes 或 PyWin32。
    • 还要注意 Popen.terminate 在 Windows 上是非常不同的。由于操作系统不支持 Unix 风格的信号,terminate 方法不能发送礼貌的SIGTERM 请求,让程序优雅地退出。它只是调用TerminateProcess 来立即终止进程,即相当于Unix 的SIGKILL 信号。 Windows 有消息而不是信号,例如WM_CLOSE。此外,由于没有进程树,terminate 不会杀死子进程。为此,您需要一个 Job 对象。 Python 的标准库不支持 Windows 消息和作业。
    猜你喜欢
    • 2016-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-19
    • 2013-12-01
    • 2015-03-07
    • 2017-06-10
    相关资源
    最近更新 更多