0

I am trying to write a program which reads from stdin and also receives user input from the tty. I would like to disable rendering of user input because it messes with my menu system and causes flickering if I redraw to remove it. However I cannot seem to use stty -echo if the script recieves input from stdin.

Here is a simplified example of the script:

trapinput

#!/bin/bash

hideinput()
{
  if [ -t 0 ]; then
     echo "Is tty"
     save_state=$(stty -g)
     stty -echo -icanon time 0 min 0
     echo -ne "\e[?1049h\r" 1>&2;
  else
     echo "is not tty"
  fi
}

cleanup()
{
  if [ -t 0 ]; then
    stty "$save_state"
    echo -ne "\e[?1049l" 1>&2;
    echo "exit tty"
  else
    echo "is not tty"
  fi
}

trap cleanup EXIT
trap hideinput CONT
hideinput

input="$(< /dev/stdin)";
echo "$input"
while true;
do
  read -r -sn1 < /dev/tty;
  read -r -sn3 -t 0.001 k1 < /dev/tty;
  REPLY+=$k1;
  echo $REPLY
done

hello.txt

helloworld!

running $ ./trapinput will echo "Is tty" on start and "exit tty" when killed along with running the rest of the program as I would expect. It also prevents the user input from being displayed directly allowing me to print it on the screen in the correct location.

However if I run $ echo "test" | ./trapinput or $ ./trapinput < hello.txt it will echo "is not tty" and stty -echo is not set causing user input to be displayed where I do not want it.

How can I disable rendering of user input but retain the ability to pipe in text/use file redirection?

4
  • 3
    hideinput < /dev/tty? Commented Mar 7, 2021 at 14:34
  • Yep this seems to have worked for hideinput. Though I'm having trouble finding information on how to specify input for trap cleanup EXIT. I've tried trap cleanup EXIT < /dev/tty trap cleanup < /dev/tty EXIT and setting stty "$save_state" < /dev/tty in the cleanup function but none of them seem to have worked leaving me with a blind tty once the script has exited. Commented Mar 7, 2021 at 15:15
  • Quoting seems to have done the trick trap 'cleanup < /dev/tty' EXIT Commented Mar 7, 2021 at 15:19
  • Do trap 'cleanup < /dev/tty EXIT` But for readability, I suggest trap_exit() {cleanup < /dev/tty; } trap trap_exit EXIT just another function. Commented Mar 7, 2021 at 15:29

1 Answer 1

2

How can I disable rendering of user input but retain the ability to pipe in text/use file redirection?

Disable the echo on where you from take the input. Do:

trap 'cleanup < /dev/tty' EXIT
trap 'hideinput < /dev/tty' CONT
hideinput </dev/tty

You could also open a file descriptor specific for input exec 10</dev/tty, etc.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.