我正在尝试通过通过Swift Pipe
执行的python脚本打开Swift Task
快捷代码
let pipe=Pipe()
let task = Process()
var env=ProcessInfo.processInfo.environment
task.launchPath = "/pythonscript.py"
let fh=pipe.fileHandleForWriting
task.arguments = ["\(fh.fileDescriptor)"]
task.launch()
Python
#!/usr/local/bin/python
import os
import sys
fd=int(sys.argv[1])
print(os.fdopen(fd, u'w'))
我从python脚本中得到的是
Traceback (most recent call last):
File "./test.py", line 7, in <module>
print(os.fdopen(fd, u'w'))
OSError: [Errno 9] Bad file descriptor
为什么python无法打开我在Swift中创建的文件描述符?
答案 0 :(得分:0)
为什么python无法打开我在Swift中创建的文件描述符?
简短回答(有点困惑):因为文件描述符是一个进程本地标识符,操作系统使用它来链接到为进程保留的打开文件信息。您不能在进程之间复制它们。
长答案:
在macOS / Unix / Linux(* nix)中,文件描述符只是一个进程本地值,操作系统使用它来链接到操作系统中适当的打开文件信息。不同的进程可以具有完全相同的文件描述符值,这些值标识完全不同的文件。因此,您不能简单地在进程之间复制文件描述符值。
在* nix中,子进程从其父进程继承打开的文件及其关联的描述符。这是在进程之间传递文件描述符的唯一方法。概述中的步骤是:
在Swift中,所有上述操作均由Process
处理,在Terminal
中,则由外壳程序处理,该外壳程序用于设置文件重定向,管道等。
要将管道连接到Python进程,您可以(a)使用Process
方法将其附加到生成的进程的标准输入或输出上; (b)创建一个命名管道,该管道带有文件路径,并将该文件路径传递给python以打开;或(c)进行底层编程,并编写一些接口C代码,该代码会进行fork
/ dup(2)
/ exec
调用,并使用已知描述符以外的管道启动Python代码标准输入或输出。
(a)最简单! (b)要求您对命名管道进行一些研究,这并不难,但是如果启用了沙箱,则需要使用沙箱,并且需要在两个进程都可以访问的目录中创建管道。 (c)最好避免。
玩得开心,如果您遇到麻烦,请提出一个新问题,以显示您尝试过的内容,出现问题的地方等。毫无疑问,有人会帮助您。
HTH