1

I'm trying to make a while loop. This loop should either echo "try again or type exit to quit" when typing gibberish or finger a user if typed the user name.

echo Please enter a user name to find.
read username
done_fn()
{
  finger $username
  exit 0 
}    
continue_fn()
{
  echo 'try again or type exit to quit'
  read exitvar
}

grep $username /etc/passwd >/dev/null
while [ $? -eq 0 ]
do
  done_fn
done

exitvar=quit

until [ $exitvar = exit ]
do
  continue_fn
  done
while [ -u $exitvar ]
do
  done_fn
done

This is everything I have got so far. Whenever I I type in a username after 'try again or type exit to quit' it will just echo it again. I would like it to finger the user instead of echoing it again. I have looked in so many places and can't find the answer.

Thank you in advance.

5
  • Can you share the output you are getting? To show the wrong behavior? Commented Apr 7, 2016 at 18:48
  • 1
    Learn to use the shell debug/trace feature and surround problematic lines with set -vx and set +vx to turn off. You'll see your code displayed, and then executed. Lines with + at the front show you what values have been substituted for variable names. In debug mode, all quoting is "boiled-down" by the debug/trace function to single quoting. You should see immediately what your problem is with grep followed by while. Good Luck! Commented Apr 7, 2016 at 19:04
  • Once I run it and type in a correct user, it fingers the user. if I type in gibberish it outputs 'try again or type exit to quit' and once I try to put in a correct user it keeps outputting 'try again or type exit to quit.' username_loop.sh Please enter a user name to find. jmalley2 Login: jmalley2 Name: Joseph Malley username_loop.sh Please enter a user name to find. asdfasdfasfasf try again or type exit to quit jmalley2 try again or type exit to quit Commented Apr 7, 2016 at 19:06
  • JJM: Best to show your tests by including them, properly formatted into the body of the Q. Use the {} format tool at the top left of the edit box on highlighted text to format as code/data/output. Again, good luck. Commented Apr 7, 2016 at 19:09
  • You have 3 loops. Try changing it in one loop with an if-statement. Commented Apr 7, 2016 at 20:53

2 Answers 2

1

You can try this:

typeset u="John Doe"
while ! grep -q "^$u:" /etc/passwd
do
    echo -n "username? "
    read u
    if [[ $u = "q" ]]
    then
            exit
    fi
done
finger $u
Sign up to request clarification or add additional context in comments.

5 Comments

You start with a name you surely won't find in /etc/passwd. Then until you find the entered name in the first field of /etc/passwd (^<name>:) you keep on asking new names. If you finally find a name, just finger it.
You can put the read in the while so you don't have to start with a sentinel value. Also I guess the finger should go inside the loop.
The loop is used to find a valid username, nothing more. If the username is 'q' then quit altogether. If a valid username is found execute a final 'finger' statement and then terminate the script. The read is already in the while and the finger shoud not be in there, since that is not in the original request.
Hmm, not sure what the OP really wants. The original script has an endless loop and the (rather dubious) requirement to type "quit" to stop suggests an endless loop to finger more and more users. Still; while read -p "user? " user && ! grep "^$user:" /etc/passwd; do ... would simplify the flow IMHO.
Yes, things can be simplified, at the cost of some of the readability. If you put in [[ $u != q ]] || exit between do and done your done... :-)
0
echo Please enter a user name to find.
read username
donev2_fn()
{
        finger $exitvar
        exit 0
}
done_fn()
{
        finger $username
        exit 0
}
continue_fn()
{
        echo 'try again or type exit to quit'
        read exitvar
        grep $exitvar /etc/passwd >/dev/null
        if [ $? -eq 0 ]
                then
                        donev2_fn
        fi
}
grep $username /etc/passwd >/dev/null
while [ $? -eq 0 ]
        do
                done_fn
done
exitvar=quit
until [ $exitvar = exit ]
        do
                continue_fn
done

I figured it out. I had to put an extra function in it. Thank you for all the help.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.