我知道我可以运行python-shell,但是我不想:我在shell中讨厌,我想要做五行Python,然后是C-d.所以“运行python-shell”不是我的问题的答案.
在终端窗口中运行的Python很好:^ D保持工作,回显不变.
Python 2.7.5,GNU Emacs 24.3.1,OS X 10.8.5
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是readline.c
中的函数,但您可以从回溯中看到,这不是在这里调用的真正的readline库,而是大部分兼容的编辑库. OS X附带BSD许可的编辑行而不是GPL许可的readline,因此这将解释为什么OS X与其他Unix的行为不同.
这与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版本,使用DYLD_PRINT_LIBRARIES
:
$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 $