如何使 readline 在 python 子进程中工作?

Posted

技术标签:

【中文标题】如何使 readline 在 python 子进程中工作?【英文标题】:How to make readline work in a python subprocess? 【发布时间】:2019-02-09 15:51:00 【问题描述】:

我在 MacOS Sierra 上的 pdb 中在一个子进程中启用了 readline 支持,但我不明白为什么它会失败,因此提出了这个问题。

请注意,我没有在我的所有 python 环境中添加 .pdbrc 文件,包括 python2 和 3 安装,以及在使用 pipenv、venv 或 pew 创建的虚拟环境中,都具有适当的 readline 支持。一切正常。

当我想在子进程中放入 pdb shell 时,就会出现问题。我使用 nodejs program 和 plugin 来在本地调用 AWS 代码。第一个 nodejs 进程启动第二个,第二个启动一个 python 进程,其中包含我常用的 pdb 代码:

import pdb; pdb.set_trace()

但是我得到的 pdb shell 没有 readline 支持。我尝试了以下替代方法,但效果不佳:

import ipdb; ipdb.set_trace()
import rlcompleter, readline
readline.parse_and_bind('tab: complete')
readline.parse_and_bind('bind ^I rl_complete')

我还添加了具有上述内容的.pdbrc 文件(减去 ipdb 导入),但无济于事。我还尝试将PYTHONSTARTUP 指向具有此内容的文件:

import rlcompleter, readline
readline.parse_and_bind('tab: complete')

它也没有帮助。人们报告说这些解决方案对他们有用,但他们一开始就没有 readline 支持(对我来说,没有这些技巧就可以正常工作)。

我还尝试修补我的 nodejs process.env.PATHprocess.env.PYTHONPATH 并添加了我安装 python 的目录,这些目录对 readline 支持无济于事。

如果有人能解释从子子进程启动 pdb 和直接从终端启动 pdb 之间是否存在根本区别(无论如何它也是一个子进程),我将不胜感激。此外,我感谢任何可能帮助我解决此问题的建议。

更新我

我注意到,即使没有 pdb,我也无法获得 readline 支持:

import code
code.interact(local=locals())

如果我运行上面的代码,我会得到一个不支持 readline 的 python shell:

Python 3.7.0 (default, Jun 29 2018, 20:13:13)
[Clang 9.1.0 (clang-902.0.39.2)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)

>>>
<pointer blinks here which is strange, it should be on the line above>

更新二

网上一些相关的帖子:

管道:https://github.com/pypa/pipenv/issues/497#issuecomment-328190362 皮尤:https://github.com/berdario/pew/issues/150

更新 III

在考虑了问题并感谢 georgexsh 评论后,我认为我的问题归结为从 nodejs 启动交互式 python REPL。它必须在自己的进程中运行,并且输入这样的按 TAB 键应该发送到 python 进程,并且它的标准输出应该打印在屏幕上。在 nodejs 中,下面的 oneliner 会做到这一点:

require("repl").start("node> ")

【问题讨论】:

这里提到的其他解决方案怎么样:***.com/questions/543196/… 你能举个例子说明如何调用 python 子进程吗? @rocksportrocker 该线程解决了我没有的问题:调试 python。我需要的是 readline 支持。 @MehdiSadeghi我认为您无法使用当前设置获得交互式外壳。当你说你想要“readline 支持”时,我猜你想要的是一个交互式 shell? @MehdiSadeghi 尝试将this line 更改为ChildProcess.spawnSync(cmd, args, stdio: 'inherit' ) 【参考方案1】:
const ChildProcess = require('child_process');                                 

const ret = ChildProcess.spawnSync('python', [],  stdio: 'inherit' ); 

为我工作。

【讨论】:

如果你像这样运行它,你会得到一个交互式 shell:ChildProcess.spawnSync('python', ['-c', 'import pdb;pdb.set_trace()'], stdio: 'inherit' ); (按 Tab 键会给你建议吗?) 对我来说,我在 python 中得到建议,但如果我使用上述参数运行你的代码,我会得到一个不给我建议的 pdb shell。按 T​​ab 键可将闪光灯向前移动。 @MehdiSadeghi 您的具体环境是什么?比如操作系统、python版本、控制台类型等。

以上是关于如何使 readline 在 python 子进程中工作?的主要内容,如果未能解决你的问题,请参考以下文章

子进程 readline 挂起等待 EOF

Go 子进程通信

如何使用python子进程调用在命令中使用管道[重复]

Python3.5子进程错误

使用 python 子进程创建计划任务

如何使子进程窗口在我的进程中显示为模态?