Python 如果在 bash 中使用管道,则使用子进程和 xclip 的脚本会挂起
Python script using subprocess and xclip hangs if piped in bash
我有一个 python 脚本需要将一些值输出到标准输入并将另一个字符串复制到剪贴板。我正在使用模块 subprocess
通过 Popen
执行 xclip
实用程序,如下所示:
# 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
可以粘贴,returns 立即。
将脚本输出通过管道传输到另一个命令时出现问题。假设有人想使用 tee
:
重定向到一个文件和标准输入
$ python clip.py|tee file.txt
该程序按预期工作,但不是 returns,即 shell 不要交还控制权。
如何解决这个问题?
一些重要信息:xclip
实用程序 forks 本身(以应对 X 上剪贴板的实现)维护可以复制的字符串,当在 shell 中使用时,它会立即 returns (它分叉到后台)。 shell 似乎将 clip.py
和 xclip
stdin/stdout 附加到 tee
。
如果使用 ps u
找到 xclip -selection clipboard
并终止命令 returns。
我正在使用 Python 3.4.
谢谢
这不是由于 xclip
的分叉,而是由于 Python 处理 Popen.wait()
的方式(通过调用 communicate()
调用)- 来自 Python perspective 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.DEVNULL
实例化 Python 3.x) 或您想要的任何其他流句柄。
我有一个 python 脚本需要将一些值输出到标准输入并将另一个字符串复制到剪贴板。我正在使用模块 subprocess
通过 Popen
执行 xclip
实用程序,如下所示:
# 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
可以粘贴,returns 立即。
将脚本输出通过管道传输到另一个命令时出现问题。假设有人想使用 tee
:
$ python clip.py|tee file.txt
该程序按预期工作,但不是 returns,即 shell 不要交还控制权。
如何解决这个问题?
一些重要信息:xclip
实用程序 forks 本身(以应对 X 上剪贴板的实现)维护可以复制的字符串,当在 shell 中使用时,它会立即 returns (它分叉到后台)。 shell 似乎将 clip.py
和 xclip
stdin/stdout 附加到 tee
。
如果使用 ps u
找到 xclip -selection clipboard
并终止命令 returns。
我正在使用 Python 3.4.
谢谢
这不是由于 xclip
的分叉,而是由于 Python 处理 Popen.wait()
的方式(通过调用 communicate()
调用)- 来自 Python perspective 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.DEVNULL
实例化 Python 3.x) 或您想要的任何其他流句柄。