【问题标题】:How to direct gnu readline away from stdout如何引导 gnu readline 远离标准输出
【发布时间】:2019-08-16 02:38:53
【问题描述】:

所以我想制作一个程序,通过重定向或交互式输入接受来自stdin 的输入。 getline 可以实现重定向读取,但我想拥有readline 的所有不错的功能用于交互式输入。该程序的目的是通过一种语言操作文本并将结果输出到标准输出(类似于 sed 所做的)。问题是我不能用readlinemy_prog > output.txt,因为无论输入到readline 中的什么,readline 的输出都会进入该文件,我什至看不到它。目前,我有一个解决方法,我只需使用rl_outstreamreadline 的输出发送到stderr。这给了我我正在寻找的行为,但是当可能有一个更直接的解决方案时,感觉就像一个黑客。我正在寻找的一个很好的例子就是 python 的作用。

python > output.txt
>>> print 'hello'
>>> exit()
cat output.txt
hello

这里有一些代码来演示我在做什么......

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#include "readline/readline.h"

int main(int argc, char** argv)
{
    char* from_stdin = malloc(512);
    char* line = NULL;

    rl_outstream = stderr;

    if(isatty(STDIN_FILENO)) {
        do {
            line = readline("");
            if(line) {
                strcat(from_stdin, line);
                strcat(from_stdin, "\n");
            } else {
                break;
            }
        } while(1);
    } else {
        size_t n = 0;
        while(getline(&line, &n, stdin) != -1)
            strcat(from_stdin, line);
    }
    puts(from_stdin);
}

接受解决方案的补丁:

--rl_outstream = stderr;
++FILE* more_hacky = fopen("/dev/tty", "w");
++rl_outstream = more_hacky;

我同意这更hacky。我可能会保留我的代码,但如果我选择,这会使 stderr 更“纯粹”地处理错误。

【问题讨论】:

  • bash(1) 在其bashline.c 函数initialize_readline 中包含相同的代码——rl_outstream = stderr;

标签: c stdin gnu readline getline


【解决方案1】:

对于它的价值,CPython确实使用STDERR_FILENO作为Readline iff !isatty(STDOUT_FILENO)的输出文件描述符,您可以使用strace等来验证这一事实。

没有重定向我们得到

% strace -o strace.out python3 && grep '>>>' strace.out
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
write(1, ">>> ", 4)                     = 4

并带有重定向

% strace -o strace.out python3 > python.out && grep '>>>' strace.out
Python 3.6.7 (default, Oct 22 2018, 11:32:17) 
[GCC 8.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> ^D
write(2, ">>> ", 4)                     = 4

替代方法是为输出流打开/dev/tty,但我觉得会更多,而不是更少,hacky。

【讨论】:

  • 是的,我只是在玩它,发现如果我执行python &gt; out.txt 2&gt; err.txt,所有 Python 标头信息和&gt;&gt;&gt; 都会转到 err.txt。但是,我编写的代码会打印到终端并且不会写入任何一个文件。
猜你喜欢
  • 1970-01-01
  • 2010-12-03
  • 2011-07-01
  • 1970-01-01
  • 2016-01-10
  • 1970-01-01
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多