Emacs shell-mode中的Python打开stty回声并打破C-d
当我在Emacs
shell缓冲区(M-x
shell)中运行交互式
Python时,它对TTY做了两件令人惊奇的事情.首先,它会打开输入回显,在Python退出后仍然存在,直到我做stty -echo.其次,它不接受C-d(或C-q C-d,即^ D)作为EOF:我必须键入quit()离开Python.如何阻止这两种行为?
我知道我可以运行python-shell,但是我不想:我在shell中讨厌,我想要做五行Python,然后是C-d.所以“运行python-shell”不是我的问题的答案. 在终端窗口中运行的Python很好:^ D保持工作,回显不变. Python 2.7.5,GNU Emacs 24.3.1,OS X 10.8.5 编辑以从shell缓冲区添加此代码段: bash-3.2$echo foo foo # no echo. bash-3.2$cat foo # I typed this. foo # cat returned it; no additional echo. bash-3.2$python Python 2.7.5 (default,May 19 2013,13:26:46) [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin Type "help","copyright","credits" or "license" for more information. >>> # C-d has no effect. C-q C-d has no effect. # not sure where this blank link has come from. >>> quit() # I have to type this to get out of Python quit() # note that it is echoed,like anything I now type. bash-3.2$echo foo echo foo # now I am getting my input echoed. foo bash-3.2$cat cat # echo of the 'cat' command. foo # my input foo # echo of my input. foo # cat's output. bash-3.2$stty -echo # turn echo back off. stty -echo bash-3.2$echo foo foo # and it's off. bash-3.2$
总结
如果您通过Macports安装Python,请安装py27-readline端口(或py35-readline或任何您的版本),并且问题已修复. 繁殖 我可以重现这一点(GNU Emacs 23.4.1; OS X 10.8.5; Python 3.3.2).这是一个新鲜的emacs -Q的会话,显示问题: $stty -a > stty-before $python3.3 Python 3.3.2 (default,May 21 2013,11:50:47) [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] on darwin Type "help","credits" or "license" for more information. >>> quit() quit() $stty -a > stty-after stty -a > stty-after bash-3.2$diff stty-before stty-after diff stty-before stty-after 2c2 < lflags: icanon isig iexten -echo echoe -echok echoke -echonl echoctl --- > lflags: icanon isig iexten echo echoe -echok echoke -echonl echoctl 7c7 < oflags: opost -onlcr -oxtabs -onocr -onlret --- > oflags: opost onlcr -oxtabs -onocr -onlret 11,13c11,13 < eol2 = <undef>; erase = <undef>; intr = ^C; kill = <undef>; < lnext = ^V; min = 1; quit = ^; reprint = ^R; start = ^Q; < status = ^T; stop = ^S; susp = ^Z; time = 0; werase = ^W; --- > eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V; > min = 1; quit = ^; reprint = ^R; start = ^Q; status = ^T; > stop = ^S; susp = ^Z; time = 0; werase = ^W; 所以你可以看到Python打开了ECHO和ONLCR标志.为什么这样做?为什么只在OS X上这样做? 什么叫tcsetattr? 我在GDB下运行Python,并在tcsetattr上设置一个断点,看看它是什么.以下是回溯的相关部分: #0 0x00007fff898e7e63 in tcsetattr () #1 0x00000001007cbe96 in tty_init () #2 0x00000001007c19cf in el_init () #3 0x00000001007d1bb7 in rl_initialize () #4 0x00000001003f10ea in PyInit_readline () #0 0x00007fff898e7e63 in tcsetattr () #1 0x00000001007cc812 in tty_rawmode () #2 0x00000001007c610f in read_prepare () #3 0x00000001007c203d in el_wset () #4 0x00000001007d554d in el_set () #5 0x00000001003f128a in call_readline () PyInit_readline和call_readline是 这与Python无关 其他交互式口译也是一样的.我发现Lua,Ruby和Sqlite3命令行解释器在Emacs中运行时也会打开终端回显.所以它似乎是某种编辑程序库的“功能”.我们通过运行这个简短的程序来测试这个理论: #include <readline/readline.h> int main() { char *line = readline("> "); return 0; } 当然,当编译时 $clang rl.c -lreadline 该程序在Emacs中运行时也会启动终端回显.但是当编译时 $clang rl.c -L/opt/local/lib -lreadline 这导致它与由MacPorts安装的真实(GNU)readline库链接,它按预期工作(不打开回显). 错误和解决方法 所以这看起来像编辑列库中的一个错误.让我们检查一下,这真的是图书馆的系统版本,而不是(说)MacPorts版本,使用 $export DYLD_PRINT_LIBRARIES=1 $/usr/bin/python dyld: loaded: /usr/bin/python dyld: loaded: /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation [... many lines omitted ...] dyld: loaded: /usr/lib/libstdc++.6.dylib Python 2.6.7 (r267:88850,Oct 11 2012,20:15:00) [GCC 4.2.1 Compatible Apple Clang 4.0 (tags/Apple/clang-418.0.60)] on darwin Type "help","credits" or "license" for more information. dyld: loaded: /System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/lib-dynload/readline.so dyld: loaded: /usr/lib/libedit.3.dylib dyld: loaded: /usr/lib/libncurses.5.4.dylib >>> 我已经向苹果报告了这个错误15184759.我知道,苹果使用报告问题的人数作为问题严重性的指标,所以如果你想要修复问题,请自己报告问题. 现在,我相信这是在最近升级到OS X的过程中出现的,所以似乎最近对libedit的更改引入了错误.以下是MacPorts安装的libedit的版本: $port installed libedit The following ports are currently installed: libedit @20110802-3.0_0 libedit @20120601-3.0_0 libedit @20121213-3.0_0 (active) 如果我及时回到2012年6月的版本: $sudo port activate libedit@20120601-3.0_0 ---> Computing dependencies for libedit ---> Deactivating libedit @20121213-3.0_0 ---> Cleaning libedit ---> Activating libedit @20120601-3.0_0 ---> Cleaning libedit 然后,这将修复我测试的所有交互式解释器(Python,Ruby,Sqlite3)的MacPorts版本中的两个问题(终端ECHO标志和破坏的C-d). 所以如果你正在寻找一个解决方法为您的问题,这是它:使用MacPorts在破解之前恢复到一个libedit版本,并将/ opt / local / bin放在你的PATH上,这样当你键入python你得到MacPorts安装Python而不是系统的一个. (可能你已经这样做了,因为我看到你的Python是2.7.5,而系统版本是2.6.7) 向上报报告 我downloaded the latest version of libedit从上游看是否有问题已经修复了.但是没有.所以我联系了Jess Thrysoee并报告了这个bug. 6.更新 截至2016年10月,libedit中的问题尚未解决.但是,如果您使用Macports,那么有一个解决方法(参见issue #48807):您可以安装pyXX-readline端口(其中XX是您的Python版本,例如py27-readline或py35-readline),它将Python与readline库链接而不是libedit.现在终端设置不变: $sudo port install py35-readline [...] $stty -a > stty-before $python3.5 Python 3.5.2 (default,Oct 11 2016,15:01:29) [GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin Type "help","credits" or "license" for more information. >>> quit() $stty -a > stty-after $diff stty-before stty-after $ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |