mgl*_*art 5 python shell subprocess piping xclip
我有一个 python 脚本,需要将一些值输出到 stdin 并将另一个字符串复制到剪贴板。我正在使用该模块通过如下方式subprocess执行实用程序:xclipPopen
# 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()))
Run Code Online (Sandbox Code Playgroud)
该脚本按预期工作:PRINT_ME在 bash 中回显PASTE_ME并可粘贴,并立即返回。
当脚本输出通过管道传输到另一个命令时会出现问题。假设有人想使用以下命令重定向到文件和标准输入tee:
$ python clip.py|tee file.txt
Run Code Online (Sandbox Code Playgroud)
该程序按预期工作但不返回,即 shell 不交还控制权。
如何解决这个问题?
一些重要信息:xclip实用程序分叉自身(以应对 X 上剪贴板的实现)维护可复制的字符串,在 shell 中使用时它立即返回(它分叉到后台)。看来 shell 正在将clip.pystdin xclip/stdout 附加到tee.
如果xclip -selection clipboard发现正在使用ps u并杀死该命令,则返回。
我正在使用Python 3.4。
谢谢
这不是由于 fork 的分叉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.
Run Code Online (Sandbox Code Playgroud)
没有测试过,但应该可以。如果您不想xclip打印到当前的 STDOUT,只需在实例化subprocess.Popen()到None(或subprocess.DEVNULL对于 Python 3.x)或您想要的任何其他流句柄时将其重定向。
| 归档时间: |
|
| 查看次数: |
1450 次 |
| 最近记录: |