LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-13-2013, 01:41 PM   #1
lgu
LQ Newbie
 
Registered: Jul 2013
Posts: 2

Rep: Reputation: Disabled
Preventing script from going back to main menu upon invalid input


Scripting beginner here, I'm trying to get the code below to automatically re-prompt for the username and password again if the user enters a blank field or if the username already exists. Right now, it's simply asking the user if they want to rerun the script again from the main menu (which I want it to continue to do if the creation of the account is successful).

Quote:
RUNSCRIPT="YES" # Allows script to run until user enters "N" for "No."
while [[ $RUNSCRIPT = "YES" ]]
do


echo "1. Create User and Password" # Main Menu options
echo "2. Reset User Password"
echo "3. Password Management"
echo "4. Create Group"
echo "5. List Users"
echo "6. Search for User"
echo "7. View User's Activity"
echo "8. Lock User"
echo "9. Unlock User"
echo "10. Delete User"
echo "11. Delete Group"
echo "12. Quit"
read -p "Select a number option from the choices above: " choice # Reads the user's numerical choice
case "$choice" in
1) read -p "Enter new username: " username
read -s -p "Enter new password: " password
if [ "$username" == "" -o "$password" == "" ]
then
echo ""
echo "Field(s) blank!"
else

egrep "^$username:" /etc/passwd >/dev/null


if [ $? -eq 0 ]; then # Checks to see if username already exists.
echo ""
echo "$username exists!"
else
read -p "Do you want this user's password to be encrypted? (Y or N) " YesNo
fi
fi

YN=`echo $YesNo | tr [:lower:] [:upper:]`
case $YN in
Y) useradd -m -p `openssl passwd -1 -salt 9Qj/F.Xw $password` $username # Creates a new username and an encrypted password
echo "New user $username created with encrypted password!"
;;
N) useradd -m -p $password $username # Creates a new username and a plain-text password
echo "New user $username created!"
;;

*) echo "Invalid choice, please try again." ;;
esac ;;
2)
3)
4)
5)
6)
7)
8)
9)
10)
11)
12)
*) echo "That is not a valid choice. Try a number from 1 to 12." ;;
esac
read -p "Select another option? (Yes/No) " YesNo # Asks the user if they want to go back to main menu
RUNSCRIPT=` echo $YesNo | tr [:lower:] [:upper:]`
clear
done



Last edited by lgu; 07-13-2013 at 01:44 PM.
 
Old 07-13-2013, 02:20 PM   #2
unSpawn
Moderator
 
Registered: May 2001
Posts: 29,415
Blog Entries: 55

Rep: Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600Reputation: 3600
Quote:
Originally Posted by lgu View Post
I'm trying to get the code below to automatically re-prompt for the username and password again if the user enters a blank field or if the username already exists.
Code:
_userPass() { # I prefer using functions. Example:
read -p "Enter new username: " _INPUT_USER
read -s -p "Enter new password: " _INPUT_PASSWD
[ ${#_INPUT_USER} -eq 0 -o "${_INPUT_PASSWD} ] && { echo "User name or password field left blank: retry.";_userPass ; }
getent "${_INPUT_USER}" passwd >/dev/null 2>&1 || { echo "User name error: retry.";_userPass ; }
useradd -m "${_INPUT_USER}" || { echo "User name creation failure, exiting.";exit 1 ; }
openssl passwd -salt $(openssl rand -base64 6) -noverify :${_INPUT_PASSWD}"|passwd --stdin "${_INPUT_USER}"
}

# You see it calls itself if necessary. Now just call the function inside your script:
_userPass
# and there you go.
*BTW do leave the "Do you want this user's password to be encrypted? (Y or N) " question out: any passwords should be encrypted by default!

BASH intros:
http://www.gnu.org/software/bash/man...ode/index.html
http://www.tldp.org/HOWTO/Bash-Prog-Intro-HOWTO.html
http://www.tldp.org/LDP/Bash-Beginne...tml/index.html

BASH scripting guides:
http://mywiki.wooledge.org/BashGuide
http://mywiki.wooledge.org/BashFAQ
http://mywiki.wooledge.org/BashPitfalls
# these are must reads so do read them!

Common questions / problems:
http://mywiki.wooledge.org/ParsingLs
http://mywiki.wooledge.orgDontReadLinesWithFor
http://mywiki.wooledge.org/UsingFind
http://mywiki.wooledge.org/Arguments
http://mywiki.wooledge.org/WordSplitting
http://mywiki.wooledge.org/Quotes
 
Old 07-13-2013, 03:46 PM   #3
lgu
LQ Newbie
 
Registered: Jul 2013
Posts: 2

Original Poster
Rep: Reputation: Disabled
Thanks so much, never thought to make it a function. Works great and it's a lot cleaner.
 
Old 07-15-2013, 04:25 AM   #4
devnull10
Member
 
Registered: Jan 2010
Location: Lancashire
Distribution: Slackware Stable
Posts: 572

Rep: Reputation: 120Reputation: 120
Just for reference, an alternate way would be to do something like:

Code:
while input is not valid
  prompt for input
loop
 
Old 07-16-2013, 07:21 PM   #5
konsolebox
Senior Member
 
Registered: Oct 2005
Distribution: Gentoo, Slackware, LFS
Posts: 2,248
Blog Entries: 8

Rep: Reputation: 235Reputation: 235Reputation: 235
You could make use of continue and break within that loop.
See
Code:
help continue; help break
 
Old 07-19-2013, 05:43 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Please use ***[code][/code]*** tags around your code and data, to preserve the original formatting and to improve readability. Do not use quote tags, bolding, colors, "start/end" lines, or other creative techniques. Thanks.


I think you should break this up into multiple parts. Start with the main menu, then have it call individual functions for doing the sub-actions. That way you can run the function menus in loops of their own until you get the input you want, and exit back to the main menu when done.

It also helps to keep clutter down and make your script more readable and debuggable. ( See Scripting With Style )

And yes, it's usually best to just use a simple while true loop, test the input, and issue continue or break commands to control whether to loop through it again.

Simplified example:
Code:
#It's better to process name and password separately

usertest(){

    local username

    while true; do

        read -p "Enter new username: " -r username

        case $username in
            '')
                echo "username blank!  Try again."
                continue
            ;;
            *[^a-z0-9]*)
                echo "username contains invalid characters!  Try again."
                continue
            ;;
            *)
               echo "username ok"
               break
            ;;
        esac

    done
      
passtest(){

    local password
    
    while true; do

        read -p "Enter new password: " -r password

    ......etc .....

}


#run the main menu

while true; do

    read -p "Select a number option from the choices above:" -r choice

    case "$choice" in

        1)
           usertest
           passtest
        ;;

        .....etc......

    esac

done
And a couple more scripting hints for you:

Code:
if [ "$username" == "" -o "$password" == "" ]; then

if [ $? -eq 0 ]
When using advanced shells like bash or ksh, it's recommended to use [[..]] for string/file tests, and ((..)) for numerical tests. Avoid using the old [..] test unless you specifically need POSIX-style portability.

http://mywiki.wooledge.org/BashFAQ/031
http://mywiki.wooledge.org/ArithmeticExpression

Code:
#YN=`echo $YesNo | tr [:lower:] [:upper:]`
This is also unneeded in shells like bash or ksh that have advanced parameter substitution patterns built in:
Code:
YN=${YesNo^^}
Also, $(..) is highly recommended over `..`.

Last edited by David the H.; 07-19-2013 at 05:50 AM. Reason: mistake and formatting fixes
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] bash back to main menu trintukaz Programming 10 10-16-2011 06:28 AM
some icon file disappeared from the place menu in the main menu of ubuntu 11.04 how t shevos37 Linux - Newbie 1 10-10-2011 02:59 PM
Send input from one script to another menu based script. simonedgcumbe Programming 9 03-24-2010 09:22 PM
How do I make my BASH script yes/no user input query terminate with 3 invalid inputs? lupusarcanus Linux - Newbie 9 03-16-2010 03:43 PM
Problem with pkgtool. Falls back to main menu PurpleMotion Slackware 5 05-12-2004 09:48 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 12:14 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration