Emacs`shell`和`eshell`输入/输出 [英] Emacs `shell` and `eshell` input/output

查看:230
本文介绍了Emacs`shell`和`eshell`输入/输出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我在Windows上的Emacs中使用 shell eshell 时,我的C程序的输出有问题,如果他们中有 scanf 。例如,这个程序
在编译后工作很好

  #include< stdio.h> 

int main()
{
printf(Hello,world!);
return 0;
}

如果我从 shell eshell 它打印如下:

  c: \\Users\xxx> a.exe 
a.exe
你好,世界!

但是这个程序不能像预期的那样工作

  #include< stdio.h> 

int main()
{
int a;
printf(Hello,world!\\\
Enter number:);
scanf(%d,& a);
return 0;
}

当我在 shell中运行它打印

  c:\Users\xxx> a.exe 
a.exe

然后卡住。如果我输入 123 然后输入它将作为

  123< =这是我输入的
你好,世界!
输入数字:

看起来像一些奇怪的缓冲行为。当我在 shell 缓冲区中查看 echo%SHELL%时,打印

  C:/App/emacs/libexec/emacs/24.5/i686-pc-mingw32/cmdproxy.exe 

为了解决 shell 的行为,我需要做些什么,并且正常工作期望?将 SHELL 变量更改为%ComSpec%没有帮助。

解决方案

当emacs在shell进程中运行外部命令时,在管道的末尾。为此,输出针对吞吐量进行了优化,而不是终端,这意味着输出以块方式缓冲。我怀疑这是你看到的。



C99标准



这种缓冲是C99标准的一部分,参见§7.19 .3 / 7


在程序启动时,预定义了三个文本流,不需要明确打开
- 标准输入阅读常规输入),
标准输出(用于编写常规输出)和标准错误
(用于写入诊断输出)。最初打开时,标准的
错误流未完全缓冲;标准输入和标准
输出流是完全缓冲的,如果且仅当流可以
确定不指代交互式设备。


GNU的建议



emacs W32常见问题解答在这种情况下应该做些什么建议: p>

W32常见问题:在Shell中缓存



禁用C缓存



正如文中提到的一种方式,程序经常得到两个世界的最好的:这是允许emacs操作,但是在管道上获得更高的性能是使用TERM变量来指示程序在emacs中运行。所以这将是一样的:

  char * term = getenv(TERM); 
if(term!= NULL&&!strcmp(term,emacs)== 0){
setvbuf(stdout,NULL,_IONBF,0);
}

只是一个例证。 stdio库的不同缓冲模式列在setvbuf的页面上。



std:cout和C ++



iostream和libc之间的关系,他们是否同步是一点点复杂。但是我怀疑您在写入 std :: cout (包括刷新)时使用 endl std :: cerr 默认情况下不缓冲。



类Unix环境中的解决方案



在具有pty的Unix环境中,可以设置与伪终端通信的过程。 expect工具包有一个名为 unbuffer 的命令。


When I use shell and eshell in Emacs on Windows I have problems with the output of my C programs if they have scanf in them. For instance this program after compilation works just fine

#include <stdio.h>

int main()
{
    printf("Hello, world!");
    return 0;
}

and if I run it from shell or eshell it prints following:

c:\Users\xxx>a.exe 
a.exe 
Hello, world!

But this program doesn't quite work as expected

#include <stdio.h>

int main()
{
    int a;
    printf("Hello, world!\nEnter number:");
    scanf("%d", &a);
    return 0;
}

When I run it in shell it prints

c:\Users\xxx>a.exe 
a.exe 

and then it's stuck. If I type 123 and then Enter it goes as

123                      <= this is what I entered
Hello, world!
Enter number:

Looks like some weird buffering behavior. When I check echo %SHELL% in the shell buffer it prints

C:/App/emacs/libexec/emacs/24.5/i686-pc-mingw32/cmdproxy.exe

What do I need to do in order to fix the behaviour of the shell and have it working as one normally would expect? Changing SHELL variable to %ComSpec% doesn't help.

解决方案

When emacs runs external commands in the shell process is on the end of a pipe. For this reason the output is optimized for throughput rather than the terminal which means the output is buffered in blocks. I suspect this is what you are seeing.

C99 Standard

This buffering is part of the C99 standard see §7.19.3/7

At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.

GNU's advice

The emacs W32 FAQ has some advice of what should be done in this case:

W32 FAQ: Buffering in Shells

Disabling buffering from C

As the article suggests one way that programs often get the best of both worlds: that is allowing emacs to operate yet getting higher performance on pipes is to use the TERM variable to indicate that the the program is running within emacs. So that would be something like:

char *term = getenv("TERM");
if (term != NULL && !strcmp(term,"emacs")==0) {
    setvbuf(stdout, NULL, _IONBF, 0);
}

Just as an illustration. The different buffering modes of the stdio library are listed on the page for setvbuf.

std:cout and C++

The relationship between iostream and libc, and whether they are synched is a little more complex. But I suspect that you are using endl in your write to std::cout which includes a flush. std::cerr is unbuffered by default.

Solution on Unix-like Environment

On Unix environments that have pty is it possible to set up the process communicating with the pseudo terminal. The expect toolkit has a command for this called unbuffer.

这篇关于Emacs`shell`和`eshell`输入/输出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆