Problem with Looping


 
Thread Tools Search this Thread
Top Forums Shell Programming and Scripting Problem with Looping
# 8  
Old 06-11-2013
Quote:
Originally Posted by RudiC
Be careful - if you don't modify the creation of the variable, you're stuck in an infinite loop. So you better not define i to be a constant. However, depending on your shell (bash in my case), this may work for you:
Code:
until typeset i=J; [ "$i" cond1 -a "$i" cond2 -a "$i" cond3 ]; do :; done

I understand the usage of until. But it doesn't work well here.
I'm so sad because if I use your code, I will not get the error indication when the variable i doesn't meet any condition.
And thanks for your advice. In fact, the variable i will be assigned the value by the command read.
e.g.
Code:
read -p "Please enter something: " i

and what I want is to check user's input whether to meet all the three conditions. If not, reenter again!
Thank you.

---------- Post updated at 05:39 PM ---------- Previous update was at 05:37 PM ----------

Quote:
Originally Posted by Corona688
This is shell, you don't "create" a variable per se. If you use a variable you haven't used before, it's just blank, not an error.
I don't create a variable. I just want to assign the value to the variable by using command read.
like this:
Code:
read -p "Please enter something: " i

THX
# 9  
Old 06-11-2013
Quote:
Originally Posted by franksunnn
I'm so sad because if I use your code, I will not get the error indication when the variable i doesn't meet any condition.
You can avoid printing the first time.

Code:
ERR=0
until [ ... ]
do
        [ "$ERR" -eq 1 ] && echo "error"
        ...
        ERR=1
done

The && is a short-form if/then. If the first command succeeds, the second command will be executed.
# 10  
Old 06-11-2013
Also Rudi's solution should work
Code:
until
 read -p "Please enter something: " i &&
 [ "$i" != 1 ] &&
 [ "$i" != 2 ] &&
 [ "$i" != 3 ]
do
  echo "error $i is invalid"
done
echo "fini with $i"

Quote:
Please enter something: 1
error 1 is invalid
Please enter something: 2
error 2 is invalid
Please enter something: 3
error 3 is invalid
Please enter something: 4
fini with 4

Last edited by MadeInGermany; 06-11-2013 at 07:19 PM.. Reason: better example
# 11  
Old 06-11-2013
Quote:
Originally Posted by MadeInGermany
Also Rudi's solution should work
Code:
until
 read -p "Please enter something: " i &&
 [ "$i" != 1 ] &&
 [ "$i" != 2 ] &&
 [ "$i" != 3 ]
do
  echo "error $i is invalid"
done
echo "fini with $i"

what if I want to print different indications?
e.g.:
if variable i equals to 1, I will get the standard output "hello!"
if variable i equals to 2, I will get the standard output "nice!"
if variable i equals to 3, I will get the standard output "good!"
# 12  
Old 06-11-2013
A simple way to do that is case.

Code:
case "$VAR" in
1)
        echo "a"
        ;;
2)
        echo "b"
        ;;
3)
        echo "c"
        ;;
esac

# 13  
Old 06-12-2013
Going back to the original posting in this thread, the following might do what you were trying to do:
Code:
#!/bin/bash
# name: loginname_validate
# purpose: to validate the loginname which is used to add a new user
i=0
while [ $i -ne 1 ]
do
        #for ksh: if ! IFS="" read -r loginname?"Please enter a new loginname: "
        #for bash:if ! IFS="" read -r -p"Please enter a new loginname: " loginname
        if printf "Please enter a new loginname: " &&
                ! IFS="" read -r loginname
        then    printf '\nUnexpected EOF or error reading login name.\n' >&2
                exit 2
        fi
        if [ -z "$loginname" ]
        then    echo 'Loginname must not be empty.'
        elif [ ${#loginname} -lt 8 -o ${#loginname} -gt 16 ]
        then    echo 'Loginname must be between 8 and 16 characters long.'
        elif [ "$loginname" == "${loginname#[_[:alpha:]]}" ]
        then    echo 'Loginname 1st character must be underscore or alphabetic.'
        elif [ "$loginname" == "${loginname#*[[:lower:]]}" ]
        then    echo 'Loginname must contain a lowercase alphabetic character.'
        elif [ "$loginname" == "${loginname#*[[:upper:]]}" ]
        then    echo 'Loginname must contain an uppercase alphabetic character.'
        elif [ "$loginname" == "${loginname#*[[:digit:]]}" ]
        then    echo 'Loginname must contain a numeric character.'
        elif [ "$loginname" == "${loginname#*[[:punct:]]}" ]
        then    echo 'Loginname must contain a punctuation character.'
        elif [ "$loginname" != "${loginname#*[![:alnum:][:punct:]]}" ]
        then    echo "Loginname can only contain alphanumeric and punctuation characters."
        elif [ -d ~"$loginname" ]
        then    printf "Loginname already exists: %s\n" "$loginname"
        else    echo 'You have entered a valid loginname.'
                i=1
                continue
        fi
        echo 'Loginname must meet following criteria:
1.  8 <= number of characters in name <= 16,
2.  1st character in name must be an alphabetic character or an underscore,
3.  name must contain at least one lowercase letter,
4.  name must contain at least one uppercase letter,
5.  name must contain at least one numeric character,
6.  name must contain at least one punctuation character, and
7.  name must not already be assigned.'
done
printf "Loop terminated with loginname set to \"%s\"\n" "$loginname"

However, I find some things VERY strange about this problem. I've never seen a Linux or UNIX system that wanted login names to contain punctuation characters like `, ~, ', ", !, #, $, ^, &, *, (, ), {, }, \, /, <, and >. The requirement to have punctuation characters sounds more like a validation check for passwords than for login names.

Notes:
  1. This script is written to be portable for use with any POSIX conforming shell. The way the ksh and bash read built-ins specify prompts are incompatible with each other. The portable if statement in brown above can be removed along with the comment at the start of one of the two lines above it for use with ksh only or with bash only.
  2. The code in orange above prevents characters in the space class and the control character class from being accepted. For login names, I would think this would be a useful addition. For passwords, I would think this code should be removed.
  3. Your original script didn't mention it, but I would think any validation program for a new user name would need to verify that the name being checked is not already in use as a login name. Unfortunately, I don't know of any portable way to test it. (A grep on /etc/passwd would work on some systems, but certainly not all.) The code in blue above tries to check this by looking for the home directory for given login name. If the shell on your system finds the home directory for the given name, it seems safe to assume that the name is already in use. If for some reason some users' directories are not accessible, some duplicate names might not be caught by this test. If this test isn't sufficient on your system, I assume that you'll be able to replace it with something that works in your environment. If you don't want a test like this at all, just remove the code in blue.
Hope this helps...
This User Gave Thanks to Don Cragun For This Post:
# 14  
Old 06-12-2013
Quote:
Originally Posted by Don Cragun
Going back to the original posting in this thread, the following might do what you were trying to do:
Code:
#!/bin/bash
# name: loginname_validate
# purpose: to validate the loginname which is used to add a new user
i=0
while [ $i -ne 1 ]
do
        #for ksh: if ! IFS="" read -r loginname?"Please enter a new loginname: "
        #for bash:if ! IFS="" read -r -p"Please enter a new loginname: " loginname
        if printf "Please enter a new loginname: " &&
                ! IFS="" read -r loginname
        then    printf '\nUnexpected EOF or error reading login name.\n' >&2
                exit 2
        fi
        if [ -z "$loginname" ]
        then    echo 'Loginname must not be empty.'
        elif [ ${#loginname} -lt 8 -o ${#loginname} -gt 16 ]
        then    echo 'Loginname must be between 8 and 16 characters long.'
        elif [ "$loginname" == "${loginname#[_[:alpha:]]}" ]
        then    echo 'Loginname 1st character must be underscore or alphabetic.'
        elif [ "$loginname" == "${loginname#*[[:lower:]]}" ]
        then    echo 'Loginname must contain a lowercase alphabetic character.'
        elif [ "$loginname" == "${loginname#*[[:upper:]]}" ]
        then    echo 'Loginname must contain an uppercase alphabetic character.'
        elif [ "$loginname" == "${loginname#*[[:digit:]]}" ]
        then    echo 'Loginname must contain a numeric character.'
        elif [ "$loginname" == "${loginname#*[[:punct:]]}" ]
        then    echo 'Loginname must contain a punctuation character.'
        elif [ "$loginname" != "${loginname#*[![:alnum:][:punct:]]}" ]
        then    echo "Loginname can only contain alphanumeric and punctuation characters."
        elif [ -d ~"$loginname" ]
        then    printf "Loginname already exists: %s\n" "$loginname"
        else    echo 'You have entered a valid loginname.'
                i=1
                continue
        fi
        echo 'Loginname must meet following criteria:
1.  8 <= number of characters in name <= 16,
2.  1st character in name must be an alphabetic character or an underscore,
3.  name must contain at least one lowercase letter,
4.  name must contain at least one uppercase letter,
5.  name must contain at least one numeric character,
6.  name must contain at least one punctuation character, and
7.  name must not already be assigned.'
done
printf "Loop terminated with loginname set to \"%s\"\n" "$loginname"

However, I find some things VERY strange about this problem. I've never seen a Linux or UNIX system that wanted login names to contain punctuation characters like `, ~, ', ", !, #, $, ^, &, *, (, ), {, }, \, /, <, and >. The requirement to have punctuation characters sounds more like a validation check for passwords than for login names.

Notes:
  1. This script is written to be portable for use with any POSIX conforming shell. The way the ksh and bash read built-ins specify prompts are incompatible with each other. The portable if statement in brown above can be removed along with the comment at the start of one of the two lines above it for use with ksh only or with bash only.
  2. The code in orange above prevents characters in the space class and the control character class from being accepted. For login names, I would think this would be a useful addition. For passwords, I would think this code should be removed.
  3. Your original script didn't mention it, but I would think any validation program for a new user name would need to verify that the name being checked is not already in use as a login name. Unfortunately, I don't know of any portable way to test it. (A grep on /etc/passwd would work on some systems, but certainly not all.) The code in blue above tries to check this by looking for the home directory for given login name. If the shell on your system finds the home directory for the given name, it seems safe to assume that the name is already in use. If for some reason some users' directories are not accessible, some duplicate names might not be caught by this test. If this test isn't sufficient on your system, I assume that you'll be able to replace it with something that works in your environment. If you don't want a test like this at all, just remove the code in blue.
Hope this helps...
You are right! Loginname doesn't look so complex. I just took a little practice.
I have a question: what if I want the loginname to start with an underscore or an alphabet and not to contain any spaces? What should I do?
Login or Register to Ask a Question

Previous Thread | Next Thread

10 More Discussions You Might Find Interesting

1. Shell Programming and Scripting

Looping problem

I need help. I am trying to get this script to send out only one email not multiple emails of the abend. Currently it will send me one then and ther with the first and second one then another email with the first second and third abend and so on. I only want one email sent. ... (2 Replies)
Discussion started by: bbcarosi
2 Replies

2. Shell Programming and Scripting

perl: problem in looping! how to get rid

Hi i just want to open 2 files and find difference between cond1 and cond2 and if the difference is greater than or equal to some number say 2 print the lines again in 2 different files. file 1 (1.txt) aqw dfr 34 poilo ggg 98 file 2 (2.txt) qww asd 28 poilo ggg 97 open FILE1,"1.txt" or... (2 Replies)
Discussion started by: anurupa777
2 Replies

3. Shell Programming and Scripting

looping problem

I have been trying to come up with a program that can do this: Say I have a file named "sir" with a single field; 10 229 288 35 83 47 3 I want to create a file "gen" with three fields with the data in file "sire" listed in field 1 while field 2 and 3 are just 1 each like this: SPARSE... (1 Reply)
Discussion started by: iconig
1 Replies

4. Solaris

SVM Solaris 8 Problem. Metastat output looping

Hi friends, I'm newbie to SVM. Just wanna try installed it on one of our server (to do mirroring for disk0 and disk1) but i think im lost until now. :( the steps i've taken is as below:- 1.prtvtoc /dev/rdsk/c1t0d0s2 | fmthard -s - /dev/rdsk/c1t1d0s2 2.metadb -a -c 3 -f c1t0d0s7... (3 Replies)
Discussion started by: kronenose
3 Replies

5. Shell Programming and Scripting

Problem with looping the directories

Hi all, I have a directory which has many sub-directories. Now, I want to check the space of each dir and redirect the output in a file if space exceeds the limit. I have already done it, but the way I did is not very good. I just listed the directories and awked the last column to get the... (5 Replies)
Discussion started by: naw_deepak
5 Replies

6. Shell Programming and Scripting

help with looping

vesselNames values: xxx yyy zzz vesselPlanned values: xxx zzz zzz zzz OIFS="" OIFS=$IFS IFS="\n" (2 Replies)
Discussion started by: finalight
2 Replies

7. Shell Programming and Scripting

for looping

I run into a issue when I try to do sorting of the following with ascending order, one round of for looping seems not working, anyone knows how to use shell or perl? $array = (5,0,3,2,7,9,8) (2 Replies)
Discussion started by: ccp
2 Replies

8. Shell Programming and Scripting

Problem with looping construct

Hi all I have tried to search for this, but keep getting a MySQL db connect error, so am posing the question here, and taking a risk of incurring the wrath of the mods with my first post... I have the following test script: #!/bin/bash HTTPD=`/bin/ps -axcu | /usr/bin/grep httpd... (6 Replies)
Discussion started by: mikie
6 Replies

9. Shell Programming and Scripting

Awk: looping problem!

I am having a problem with awk when I run it with a loop. It works perfectly when I echo a single line from the commandline. For example: echo 'MFG009 9153852832' | awk '$2 ~ /^0-9]$/{print $2}' The Awk command above will print field 2 if field 2 matches 10 digits, but when I run the loop... (5 Replies)
Discussion started by: cstovall
5 Replies

10. UNIX for Dummies Questions & Answers

Help with looping

Hi, Actually I have a file which consists data . for eg names. Then I want my sql query to read this file and produce the output. Currently I am using this FOR EG : FILENAME is NAMES for i in `cat NAMES` { sqlplus -s $CONNECTID << EOF spool rooh set heading off select... (1 Reply)
Discussion started by: rooh
1 Replies
Login or Register to Ask a Question