3

Is there any way to display the shell's standard input linefeed separately from the standard output stream? This seems like a very basic question, but I haven't noticed many people asking about it for some reason.

In particular, I'm trying to avoid my input getting spliced by standard output (and standard error) printouts. For example, I'm trying to avoid the following scenario:

$while true; do echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; done
Hello there. Sorry to barge in; were you busy?
whaHello there. Sorry to barge in; were you busy?
t Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
stopHello there. Sorry to barge in; were you busy?
 Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
whyHello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?

Instead, I want something that looks like this:

$while true; do echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; done
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>what
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>stop
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>why
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
Hello there. Sorry to barge in; were you busy?
>>unsent linefeed content appears fixed over here

Is this a feature available for common Linux terminal implementations? If not, is there an ncurses program capable of doing this?

Navneeth
  • 131

2 Answers2

1

Is this a feature available for common Linux terminal implementations?

I don't think there is a general solution available. It's not very common for normal scripts to display output and accept input at the same time - that is essentially behavior of multi-threaded application, and people usually compile graphical output libraries like ncurses into them...

If not, is there an ncurses program capable of doing this?

If it is, i never heard of it. You'd need it to run as parallel process to the main script/application, meaning you would have to use forking, couldn't pipe input into it... it would be complicated.

I think you have only two options - either write that ncurses wrapper yourself or split it into two terminals. In first terminal you run the script and accept stdin but stdout and stderr are redirected into a named pipe.

$ mkfifo myoutput
$ function blah() { 
>   while true; do 
>     echo "Hello there. Sorry to barge in; were you busy?"; sleep 1.5; 
>   done
> }
$ blah 2>&1 >./myoutput

Now you can read the output at another terminal with cat ./myoutput while stdin is still accepted at the original terminal.

Marek Rost
  • 2,136
  • 12
  • 16
1

It can be done, though requires your program to handle several things. In particular, the program will need to know everything the user has typed, which means the program will need to put the terminal into raw mode (turn off ICANON, see the termios manual page) and to deal with individual keystrokes as they come in. Then when the program needs to periodically print something, it can use a carriage return print (or a suitable escape sequence to move the cursor where it needs to go, though usually these are abstracted by ncurses) to wipe out what the user has typed; assuming the user has typed what but not hit return, the program would perform the equivalent of the sleep and subsequent overwriting echo -e:

 echo -n what; sleep 1; echo -e "\rHello there..."

And then your program will need to redisplay what the user has typed but was overwritten by the above; hence the need to operate the terminal in raw mode and buffer that information. In a shell program, stty could be used to set raw mode, and then some shells have suitable read for character-by-character reading (oh and then you may also need to handle control+c and other special characters yourself...)

thrig
  • 816