如何使 gnu readline 远离 stdout
How to direct gnu readline away from stdout
所以我想制作一个程序,通过重定向或交互式输入接受来自 stdin
的输入。 getline
可以实现重定向读取,但我想在交互式输入方面拥有 readline
的所有优点。该程序的目的是通过一种语言来操作文本并将结果输出到标准输出(类似于 sed 所做的)。问题是我不能用 readline
做 my_prog > output.txt
因为无论输入什么 readline
readline 的输出都会进入那个文件,我什至看不到它。目前,我有一个解决方法,我只使用 rl_outstream
将 readline
的输出发送到 stderr
。这给了我我正在寻找的行为,但当可能有更直接的解决方案时,感觉就像一个 hack。我正在寻找的一个很好的例子是 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 更多 "pure" 错误。
对于它的价值,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
,但我觉得 that 会更多,而不是更少,hacky。
所以我想制作一个程序,通过重定向或交互式输入接受来自 stdin
的输入。 getline
可以实现重定向读取,但我想在交互式输入方面拥有 readline
的所有优点。该程序的目的是通过一种语言来操作文本并将结果输出到标准输出(类似于 sed 所做的)。问题是我不能用 readline
做 my_prog > output.txt
因为无论输入什么 readline
readline 的输出都会进入那个文件,我什至看不到它。目前,我有一个解决方法,我只使用 rl_outstream
将 readline
的输出发送到 stderr
。这给了我我正在寻找的行为,但当可能有更直接的解决方案时,感觉就像一个 hack。我正在寻找的一个很好的例子是 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 更多 "pure" 错误。
对于它的价值,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
,但我觉得 that 会更多,而不是更少,hacky。