Bash: After redirected input file is done, allow user to control application via STDIN 1


Recently, we needed to start an application using a script, which application had its own CLI.
After starting it, we had to feed it with some input to configure it before handing it over to the end user.

The application we used was named dog. We wrote into a plain text file (named food) the commands that we needed to feed the application and then we started the execution using a plain input redirect like so dog < food;.
Doing so, resulted into properly feeding the dog application the food data  but it would cause the application to terminate immediately after the food was done as it would also feed the EOF (End Of File) directive to dog.
Apparently, the application after receiving the EOF, it would then terminate without allowing the end user to take control.

To mitigate the problem, we used the cat command to concatenate the input file along with the stdin stream, permitting us to first feed all the data in the food file and then allow the user to input data using the standard input stream.
Our final command resulted in the following solution as below

cat <(cat food) - | dog;

Where - is the special sign for standard input stdin.
cat food can be of course replaced with other commands that produce output on the standard output (stdout).

A bad side-effect of this solution, is that we lost some functionality of the terminal including, but not limited to, using the backspace and navigation.

This post is also available in: Greek


Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

One thought on “Bash: After redirected input file is done, allow user to control application via STDIN

  • Shaun Pankau

    If dog was a bash script, it is possible to read from stdin if it was redirected, reset stdin back to the terminal if it was redirected, and then read from the terminal. Doing so addresses the backspace and navigation issues. Here is an example of how it could be done:

    #/usr/bin/env bash
    #
    # This script reads any piped or redirected text from stdin
    # then prompts user for an interactive response.
    #
    # $ ./dog
    # Enter a string? For cats
    # String entered: For cats
    #
    # $ echo -e “This is\nfood” | ./dog
    # Text supplied: This is
    # Text supplied: food
    # Enter a string? For cats
    # String entered: For cats
    #
    # $ ./dog < EOF
    # Text supplied: This is
    # Text supplied: food
    # Enter a string? For cats
    # String entered: For cats

    # read from stdin if stdin was piped or redirected
    if [[ ! -t 0 ]]
    then
    while read line
    do
    echo “Text supplied: $line”
    done

    # reset stdin to read from terminal
    exec 0 /dev/tty
    fi

    # prompt for more input
    read -p “Enter a string? ” string
    echo “String entered: ” $string