使用Python subprocess.call()启动ncurses进程
我正在尝试从 SCons 的 SConstruct 脚本中调用 ct-ng(http://crosstool-ng.org/),也就是从 Python 中调用它。
我使用的方法如下:
ret = subprocess.call(["/mnt/build/pw_build/crosstool-ng/bin/ct-ng menuconfig"], env=env_cross,shell=True)
crosstool-ng 使用 ncurses 来给用户展示一个菜单:
不幸的是,当我尝试在菜单中导航时,我遇到了:
使用 cat 命令显示按箭头键时的序列,我看到:
:/mnt/build$ cat > /dev/null
^[OA^[OD^[OB^[OC^[OA^[OB^[OD^[OC^[OA^[OB
看起来可能是有什么东西把序列中的转义字符去掉了。
当我在终端的命令行中直接调用 ct-ng 脚本时,它是正常工作的,但当我用 subprocess.call() 调用时就出问题了。
我的环境包括:
- xfce4-terminal 0.6.3
- Linux 3.13.0-32-lowlatency #57-Ubuntu SMP PREEMPT Tue Jul 15 04:08:59 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
- Python 2.7.6
- NCURSES_VERSION "5.9"
- GNU Make 3.81
- crosstool-NG 版本 1.19.0
我遇到的问题是一个已知的问题吗?我还有什么其他需要做的吗?
更新: 感谢 Eric... 这让我走了 0.5f 的路程... 我现在可以导航菜单了,但仍然留下了一些杂乱:
2 个回答
经过仔细追踪执行过程,我发现有一个脚本在重定向到 tee
,这就是导致问题的原因。
感谢所有关注这个问题的人。我本应该一开始就发现这个问题,抱歉让大家费心了。
如果你想在Python中运行curses程序,我建议你使用pexpect这个工具。
比如,下面这个简单的程序会启动一个vim
的副本,添加一些文本,然后切换到命令模式,输入:w命令,接着和用户互动(让用户继续编辑或者做其他事情)。最后控制权会返回给Python:
#!/usr/bin/env python
import pexpect
child = pexpect.spawn("/usr/bin/vim")
child.send('a\n\nThis is another test.')
child.send('\x1b')
child.send(':w! test.txt\n')
child.interact()
你还可以给interact方法传递一些参数,比如转义字符和输入输出的过滤函数。不过这些参数会有点复杂。(另一方面,这样你就可以在用户和运行的应用程序之间,建立一个自定义的键盘宏系统,使用.spawn()
来实现)。
(顺便说一下:你可以把想要的按键序列发送到这个ct-ng
对话框/菜单中……这只是要弄清楚这些序列在你的终端设置下应该是什么。例如,在我的MacOS X的iTerm中,使用TERM=xterm-256color时,"下箭头"的光标移动会显示为^[[B(也就是[Esc][Bracket][B])。在Python字符串中,这个表示为'\x1b[B')。