【问题标题】:Write to file descriptor 3 of a Python subprocess.Popen object写入 Python subprocess.Popen 对象的文件描述符 3
【发布时间】:2011-05-18 19:46:49
【问题描述】:

如何写入 subprocess.Popen 对象的文件描述符 3?

我正在尝试使用 Python 在以下 shell 命令中完成重定向(不使用命名管道):

$ gpg --passphrase-fd 3 -c 3<passphrase.txt < filename.txt > filename.gpg

【问题讨论】:

  • 我很想知道这一点。我不认为这是直接可能的。 Popen 对象提供标准输出、标准输入和标准错误的句柄。我不知道其他人。
  • 也许是 OT,但您知道为 GnuPG 提供 Python API 的 python-gnupg 项目吗?请参阅code.google.com/p/python-gnupg 了解更多信息。 (披露:这是我的项目)
  • 我研究了一些 Python gpg 包装器,你的看起来很可行,但我当前的项目太小了,我正试图最小化依赖关系。
  • 我也对此感兴趣。但是看起来python子进程模块仍然没有简单的shell重定向那么强大。

标签: python subprocess


【解决方案1】:

子进程proc 继承父进程中打开的文件描述符。 所以你可以使用os.open打开passphrase.txt并获取其关联的文件描述符。然后,您可以构造一个使用该文件描述符的命令:

import subprocess
import shlex
import os

fd=os.open('passphrase.txt',os.O_RDONLY)
cmd='gpg --passphrase-fd {fd} -c'.format(fd=fd)
with open('filename.txt','r') as stdin_fh:
    with open('filename.gpg','w') as stdout_fh:        
        proc=subprocess.Popen(shlex.split(cmd),
                              stdin=stdin_fh,
                              stdout=stdout_fh)        
        proc.communicate()
os.close(fd)

要从管道而不是文件中读取,您可以使用os.pipe

import subprocess
import shlex
import os

PASSPHRASE='...'

in_fd,out_fd=os.pipe()
os.write(out_fd,PASSPHRASE)
os.close(out_fd)
cmd='gpg --passphrase-fd {fd} -c'.format(fd=in_fd)
with open('filename.txt','r') as stdin_fh:
    with open('filename.gpg','w') as stdout_fh:        
        proc=subprocess.Popen(shlex.split(cmd),
                              stdin=stdin_fh,
                              stdout=stdout_fh )        
        proc.communicate()
os.close(in_fd)

【讨论】:

  • 酷。因此,如果我不想将密码保留在文件中,我可以创建一个管道,将密码写入其中,并将其输出 fd 作为继承的文件描述符,gpg 将在其中获取密码?
  • @aaronstacy:是的,我测试它是肯定的。 (上面发布的代码)
  • 请注意,如果密码大于操作系统的管道缓冲区,理论上存在死锁的危险。为了安全起见,您必须进行 IO 多路复用,并在启动进程后写入密码。
  • 快速更新:在 Python 3 中,close_fds 默认为 True,因此您需要将 pass_fds=[in_fd] 添加到 Popen 构造函数以使其工作。
  • 稍微解释一下:在 Python 中,无法执行“将子文件描述符 3 连接到父文件描述符 4”之类的操作; 然而在这种特殊情况下(例如)代码从passphrase.txt打开文件描述符4,然后使用pass_fds将孩子的fd4连接到父母的fd4,然后告诉孩子从文件中读取描述符 4 而不是 3。从 Python 调用 bash,它会正确地为子级重定向 fds。
猜你喜欢
  • 1970-01-01
  • 2019-06-20
  • 1970-01-01
  • 1970-01-01
  • 2012-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-28
相关资源
最近更新 更多