我有一个python脚本需要输出一些值到stdin并将另一个字符串复制到剪贴板。我使用模块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()))
该脚本按预期工作:{b}中回显PRINT_ME
,可以粘贴PASTE_ME
,并返回imediatly。
当脚本输出通过管道传送到另一个命令时,会出现问题。假设有人想使用tee
重定向到文件和标准输入:
$ python clip.py|tee file.txt
该程序按预期工作但不返回,即shell不会给予控制权。
如何解决这个问题?
一些重要信息:xclip
实用程序 forks 本身(以应对X上剪贴板的实现)维护字符串可用于复制,当用于shell它立即返回(它分叉到背景)。 shell似乎将clip.py
和xclip
stdin / stdout附加到tee
。
如果使用xclip -selection clipboard
找到ps u
并且命令返回被杀死。
我使用的是Python 3.4 感谢
答案 0 :(得分:2)
这不是由于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
(或{3.}为Python 3.x)时重定向它或者你想要的任何其他流句柄。