0

I have a program that asks the user for input and provides interactive features such as moving the cursor, deleting text, and more. After the user completes entering the input, the program clears the input line completely and prints the user query to stderr. To enable the interactive features, the terminal is put in raw mode and escape sequences are used.

I want to capture the stderr output of this program into a variable without interfering with its stdout (i.e. without messing up the interactive feature). Most solutions recommend something like program 2>&1 1>/dev/null | read query, but this destroys the stdout and overwrites it with the stderr. The closest I could manage to get was to write to a temporary file and then use read on it like so:

program 2> tempfile.txt; read query < tempfile.txt

I'm looking for a solution that avoids using temporary files and directly pipes the stderr into the read command's stdin (or captures the stderr into a variable some way without messing up the stdout). For example in fish shell this can be done like so (as mentioned in the docs):

program 2>| read query

How can I achieve the same in bash? Is there an easier solution for zsh?

muru
  • 72,889
  • 1
    That's quite an unusually way for a program to behave. Usually output goes to stdout and prompt strings and errors or anything else intended for the interactive user go to stderr. – Stéphane Chazelas Jun 29 '23 at 09:28
  • @StéphaneChazelas I didn't know that prompts were usually written to stderr, thanks for pointing it out. My goal with the program mentioned in the question is to replace the interactive prompt in a shell like zsh/bash/fish with a custom readline-like implementation that supports more features like snippets, autosuggestions, etc. The program will be run just before the builtin prompt of the host shell renders, and the interactive input obtained will be inserted into the original prompt and executed. (cont.) – sudormrfbin Jun 29 '23 at 10:32
  • I searched around and found historical reasons pertaining to the usage of stderr for prompts (like POSIX compliance); are there any practical reasons to prefer stderr over stdout in this particular case? The program is meant to be run interactively only since it doesn't make much sense to have interactive features in a scripting context. – sudormrfbin Jun 29 '23 at 10:33
  • 1
    It's not related to POSIX compliance. The idea is that if someone runs a command with redirected stdout (to a pipe of a file), the user still need to see prompts that require his interactive intervention. For instance, try running sudo echo > /dev/null. You'll see it asks for the password even though stdout is redirected to /dev/null. That's because this prompt goes to stderr. If it went to stdout, you wouldn't have seen the prompt asking for the password, and you won't understand why your sudo command is stuck. – aviro Jul 03 '23 at 09:49

0 Answers0