4

我有一个 python 脚本,需要将一些值输出到标准输入并将另一个字符串复制到剪贴板。我正在使用该模块通过以下subprocess方式执行该xclip实用程序Popen

# clip.py
import subprocess
from subprocess import Popen

print('PRINT_ME')
p1 = Popen(['xclip', '-selection', 'clipboard'], stdin=subprocess.PIPE)
p1.communicate(input=('PASTE_ME'.encode()))

该脚本按预期工作:PRINT_ME在 bash 中回显,PASTE_ME可以粘贴,并立即返回。

将脚本输出通过管道传输到另一个命令时会出现问题。假设一个人想使用以下命令重定向到一个文件和标准输入tee

$ python clip.py|tee file.txt

该程序按预期工作但不返回,即shell 不给予控制权。

这怎么可能解决?

一些重要信息:该xclip实用程序自行分叉(以应对 X 上剪贴板的实现)维护可复制的字符串,当在 shell 中使用时它立即返回(它分叉到后台)。似乎外壳将stdin/stdout都附加clip.py到. 如果使用并杀死命令返回。 xcliptee
xclip -selection clipboardps u

我正在使用 Python 3.4。
谢谢

4

1 回答 1

4

这不是由于分叉xclip,而是由于 Python 的处理方式Popen.wait()(通过您的调用调用communicate()) - 从 Python 的角度来看xclip(默认情况下为静音)没有关闭它的流,所以它等待......这就是为什么除了 Python 之外一切正常的原因在将p1.communicate()其流传输到其他东西时(在这种情况下)移动到您的线路tee- 它等待其所有文件句柄关闭......

您可以手动打开和关闭您的流,或者只配置xclip将 STDIN 过滤为 STDOUT 并让 Python 满意:

import subprocess

p1 = subprocess.Popen(['xclip', '-selection', 'clipboard', '-f'], stdin=subprocess.PIPE)
p1.communicate(input=('PASTE_ME'.encode()))
# etc.

没有测试它,但它应该工作。如果您不想xclip打印到当前的 STDOUT,只需在实例化subprocess.Popen()None(或subprocess.DEVNULLPython 3.x)或您想要的任何其他流句柄时将其重定向。

于 2017-06-14T21:50:49.703 回答