Sophia Koulen
Sophia Koulen

Reputation: 312

How to control input echoing in non-interactive mode with readline 8.2?

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:

  1. readline is echoing input to stdout, regardless of whether stdin, stdout or stderr are connected to a terminal
  2. when neither stdout or stderr are connected to the terminal, you can't see what you're typing.

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

Answers (1)

John Bollinger
John Bollinger

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 the read 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

Related Questions