【问题标题】:Emacs `shell` and `eshell` input/outputEmacs `shell` 和 `eshell` 输入/输出
【发布时间】:2015-09-03 16:02:04
【问题描述】:

当我在 Windows 上的 Emacs 中使用 shelleshell 时,如果我的 C 程序的输出中有 scanf,我会遇到问题。比如这个程序 编译后就好了

#include <stdio.h>

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

如果我从 shelleshell 运行它,它会打印以下内容:

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

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

#include <stdio.h>

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

当我在 shell 中运行它时,它会打印出来

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

然后卡住了。如果我输入123,然后输入Enter,则为

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

看起来有些奇怪的缓冲行为。当我在shell 缓冲区中检查echo %SHELL% 时,它会打印出来

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

我需要做什么才能修复shell 的行为并使其正常工作?将 SHELL 变量更改为 %ComSpec% 没有帮助。

【问题讨论】:

    标签: shell emacs


    【解决方案1】:

    当 emacs 在 shell 进程中运行外部命令时,它位于管道的末端。出于这个原因,输出针对吞吐量而不是终端进行了优化,这意味着输出以块的形式缓冲。我怀疑这就是你所看到的。

    C99 标准

    此缓冲是 C99 标准的一部分,请参阅 §7.19.3/7

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

    GNU 的建议

    emacs W32 FAQ 有一些关于在这种情况下应该做什么的建议:

    W32 FAQ: Buffering in Shells

    从 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 的命令。

    【讨论】:

    • 有趣地使用std::coutstd:cin 和g++ 编译器工作就找到了。
    • 正如常见问题解答所说,您遇到了来自 libc 的缓冲。 Stdio 检测到您的输出不是 tty 并选择缓冲以获得更高的吞吐量,可能是块缓冲。
    • 我怀疑您无意中以不同的方式使用 C++,我已将上面的答案更新为更明确:尽管这只是详细说明常见问题解答所说的内容。
    • 好的。这似乎可行,尽管现在我必须更改 C 程序而不是 emacs 的术语设置,这将是一种首选方式
    • 如果您在 Unix 上,您可以使用 pty 设置进程。为此,Expect 有一个名为 unbuffer 的命令。 Windows 端口之一是否可以工作。我看到一个报告说 cygwin 端口并不总是工作:superuser.com/questions/840903/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-13
    • 2011-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多