Reputation: 312
As part of a school project, we have to write a simplified shell and are instructed to imitate Bash's behavior. While trying to understand how to make the simplified shell work in non-interactive mode, I noticed 2 issues:
What i need is:
I saw here (Why does readline() echo stdin to stdout?) that you can configure this behaviour using the rl_outstream
variable, but this doesn't seem enough.
In non-interactive mode, i need to disable input echoing completely. But setting rl_outstream = NULL
just makes it echo to stdout.
Here is the code that shows my issue:
#include <stdio.h>
#include <readline/readline.h>
#include <readline/history.h>
#include <stdlib.h>
#include <unistd.h>
int main()
{
char *line;
if (isatty(2))
rl_outstream = stderr;
while (1)
{
if (isatty(0) && isatty(2))
line = readline("prompt> ");
else
line = readline("");
if (!line)
break ;
free(line);
}
return (0);
}
Make sure to compile with readline 8.2.1, since this code seems to behave differently with older versions of readline.
When running ./a.out >out
or ./a.out 2>err
, i get the result i want.
My problem is with the following cases:
./a.out >out 2>err
Problem: Can't see what you type
./a.out <infile
Problem: Input is echoed to stderr
Upvotes: 1
Views: 341
Reputation: 180073
Frame challenge:
The Bash manual page has this to say about readline:
This is the library that handles reading input when using an interactive shell, unless the
--noediting
option is given at shell invocation. Line editing is also used when using the-e
option to theread
builtin.
(Emphasis added)
We can conclude, then, that Bash itself does not use readline when running as a non-interactive shell. You can even disable readline for interactive Bash.
Thus, you should consider emulating Bash in this regard too, and instead of struggling with making readline work as you want for the non-interactive case, just don't use it in that case.
Upvotes: 1