0

I am trying to create a nested case statement in which user input is expected (Y/N). However, the system never waits for the input and always goes to the third option, "Please answer yes or no". Can anyone tell me what I am missing?

Here is the case statement

 #!/bin/bash

SERVSTAT=/mnt/support/scripts/log/serverstatus.txt
FUSE_PATH=/home/jet/instances/
LOG=data/log/karaf.log
echo " " >  $SERVSTAT
STATUS=status

find /etc/init.d/* -name '*service' -print0 | while IFS= read -r -d '' FILE;
do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
APP_NAME=`echo ${FILE:12} | sed 's/-service//'`
        OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
    *not* )
        echo "Do you wish to start $APP_NAME ?"
        read  yn
        case $yn in
         [yY] | [yY][Ee][Ss] )
                $FILE start
                tail -f $FUSE_PATH/$APP_NAME/$LOG
                ;;
         [nN] | [n|N][O|o] )
                ;;
        * )
        echo "Please answer yes or no.";;
        esac
        ;;
       * )
        echo "App $APP_NAME is running"
esac
fi
done

I'm Trying to execute this in RHEL 6

Ubuntuser
  • 101
  • The -p flag to read takes an argument, which is swallowing your variable name. Try read -p foo yn. – MadHatter Jun 26 '14 at 07:34
  • If it never waits for input, then your error happens before you ever get to the case statement. – gbarry Jun 26 '14 at 07:45
  • @gbarry: thanks I am still not able to figureout why this is happening. Updating the question with full script –  Jun 26 '14 at 08:38

1 Answers1

1

The read command is happening in a pipeline -- it's inside the while loop, which has its input redirected from the output of the find command -- so when it reads, it's reading from the list of files find generated, rather than the terminal. The simplest way I know to fix this is to send the list of files over something other than standard input, so standard input can still be used for other things (like user confirmation). As long as you aren't using file descriptor #3 for something else, this should work:

# ...
while IFS= read -r -u3 -d '' FILE; do
    # same inside of the loop...
done 3< <(find /etc/init.d/* -name '*service' -print0)

The -u3 tells read to read from FD3, and the 3< <(find...) redirects FD3 from the output of the find command. Note that the <( ) (known as process substitution) is a bash extension (not available in plain posix shells), so you should only use this in scripts you start with #!/bin/bash (not #!/bin/sh).

  • 1
    <(...) is a ksh extension (like read -u and read -d) later adopted by bash and zsh. Note that in this case, you probably want for FILE in /etc/init.d/*service. – Stéphane Chazelas Jun 28 '14 at 11:54