Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

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

share|improve this question

migrated from serverfault.com Jun 28 at 11:34

This question came from our site for professional system and network administrators.

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

1 Answer 1

up vote 1 down vote accepted

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).

share|improve this answer
    
Thanks so much. That was very helpful, the description! –  user216069 Jun 27 at 6:32
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 at 11:54

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.