如何从子进程访问子进程 Popen pass_fds 参数?

How to access subprocess Popen pass_fds argument from subprocess?

所以标题有点长,但这是我在网上唯一找不到的,稍微搜索了一下。如何从子进程访问 pass_fds 参数?

# parent.py
import subprocess

subprocess.Popen(['run', 'some', 'program'], pass_fds=(afd, bfd))

# child.py
import subprocess

# need to access pass_fds argument? but how?

您需要明确通知 child 以某种方式传递的 fds。大多数 common/simple 机制是:

  1. 通过为 child
  2. 设置的环境变量
  3. 通过参数传递给 child
  4. (不太常见,但可能)写入 child 的 stdin

当然这都需要child的配合;它需要定义一个接口来通知它传递的 fds。

openssl 的命令行工具支持所有这些机制以实现类似的目的(将密码短语传达给 child 而无需将其放在命令行上)。您传递 -pass 和定义在哪里查找密码的第二个参数。如果第二个参数是 stdin,它从 stdin 读取,如果它是 -pass fd:#(其中 # 是 fd 号)它从提供的任意文件描述符读取,-pass env:var(其中var是环境变量的名称)从环境等读取

嗯,也许这不是最好的技术答案,但我想深入了解文件描述符。根据您的问题,我制作了这两个脚本。 Os 创建管道,父级通过 pass_fds 元组向子级发送描述符。 python docs , os.read() 描述中的更多信息。之后,父进程的 fdw 被作为字节推送到子进程,然后用于发回一些答案。

希望对您有所帮助。

编辑: 在 google 个论坛中找到 this post

##### child.py
import subprocess, os

fdr_data = os.read(3,20) # 3 is inherited by pass_fds    
fdw = int(fdr_data)      # 4

print("CHILD fdw = ", fdw , "\n")

os.write(fdw, bytes("some answer".encode())) 
exit()


##### parent.py
import subprocess, os, time

fdr, fdw = os.pipe() # new file descriptor read , fd write
print("PARENT", "fdr = ", fdr , " fdw = " , fdw)

subprocess.Popen(['python3','child.py'], pass_fds=(fdr, fdw))    
os.write(fdw, bytes("{}".format(fdw).encode())) # pipe file descriptor write (out 4)

time.sleep(1)   # so subproc can execute

read_pipe = os.read(fdr, 20) # pipe file descriptor read (in 3)    
print("PARENT" , read_pipe.decode())