Solved

Unix Shell script with input validation

Posted on 2010-09-15
19
2,248 Views
Last Modified: 2013-12-26

There's a tendency that inputs entered contain "hidden" characters when a user
pressed "Backspace" or accidentally press Control characters or there has been
cases where the user entered an invalid length input.

I need a script (preferably Korn or Bournes Shell script & not Perl) to be able to validate
the inputs :

#/bin/ksh
#
read idnum?"Pls enter your identification number: "
typeset -u idnum
... validation codes which I need help with .....
a_processing_script $idnum

The validation criteria for idnum are :
a) it has to start with 's' or 'S' & if it doesn't, prompt user again to re-enter &
      echo to say it has to start with 'S'
b) total length of idnum including the first character 'S' (but exclude the <ENTER> which
     the user hit after entering everything) should be between 8-9 & if not, prompt user
      to re-enter & echo to say length of identification number must be between 8-9
c) all characters after S should be numeric values of 0-9 except the last character
      which can be either a numeric or an alphabet
d) if a "space", "backspace" or hidden characters or other than numbers & the last
     character (being a numeric or alphabet) is entered (as mentioned in point c above),
     prompt user to re-enter & echo  to say  a corrupt/invalid character has been entered
0
Comment
Question by:sunhux
  • 7
  • 5
  • 4
19 Comments
 
LVL 14

Accepted Solution

by:
sentner earned 380 total points
ID: 33685274
Try this...

#!/bin/ksh



TEXT=""



while [ -z "$TEXT" ]; do

   printf "Enter text: "

   read TEXT

   echo $TEXT | awk '{

      l=length($0)

      if (l<8 || l>9)

         print "Length must be 8 or 9 characters"

      else

         if (match ($0,"^[sS]"))

            if (match($0,"^[sS][0-9]+[0-9a-zA-Z]$")) {

               exit(0)

            }

            else

               print "Invalid or corrupt character has been entered"

         else

            print "Must start with S"

      exit(255)

      }' || TEXT=""

done

~

Open in new window

0
 
LVL 31

Assisted Solution

by:farzanj
farzanj earned 120 total points
ID: 33687990
It is really very simple.  You can enjoy the power of regular expressions which are available in both Korn and Bash.  You don't necessarily need to go to Perl.  I am giving you a simple idea and you can tailor it to get the kind of custom messages you want.  Here it is.

#So initially idnum is not set
idnum=''

#you need to take input until you are happy
until [[ $idnum = @([sS]){8,9}(\d) ]]
do
     echo "Correct ID: S or s followed by 8 to 9 digits"
      read idnum
done

So when your condition is satisfied you will not take any more inputs of idnum.

Enjoy regular expressions
0
 
LVL 14

Expert Comment

by:sentner
ID: 33688057
Indeed, regular expressions are what I used in my version too.  It can be shortened if you don't need to specifically call out each error condition, but I wanted to stick to your original specifications.
0
 

Author Comment

by:sunhux
ID: 33690953

regex is not supported on my HP-UX B11.11 but I guess the syntax you gave
doesn't need "regex" command : I'm not sure why  there's error in the script:

Sentner's script is almost there but if I entered a leading "space" character
while being read for input, it fails to detect it.  Pressing <Backspace> appeared
to be not detected, perhaps my BS works correctly?


For Farzani, script syntax issue

# ksh -v addid
idnum=''

#you need to take input until you are happy
until [[ $idnum = @([sS]){8,9}(\addcm2: syntax error at line 4 : `(' unexpected
root@nsppwas2:/usr/bin > more addcm2
idnum=''



I then inserted a "read idnum"  before the until loop but it did not help:
# ksh -v addid
idnum=''
read idnum
s25666988

#you need to take input until you are happy
until [[ $idnum = @([sS]){8,9}(\addid[2]: syntax error at line 5 : `(' unexpect                ed
0
 
LVL 31

Expert Comment

by:farzanj
ID: 33691160
What version of Korn shell do you have in your system?  Korn 87?
0
 
LVL 14

Assisted Solution

by:sentner
sentner earned 380 total points
ID: 33693034
The reason my version ignores leading or trailing spaces is due to the fact that "read" drops any leading or trailing spaces.  Therefore, they never end up as part of the $TEXT variable, and thus are not hidden characters.  Do you really need to detect those since they aren't in there?

0
 

Author Comment

by:sunhux
ID: 33693398

Ok, then Sentner's script is fine, I'll probably test with some other hidden characters
tomorrow just to be exhaustive.  I'm at GMT+8 timezone

Hi Farzani, I'm now home, so have no access to the HP-UX server but I recalled I'm
actually in Bourne Shell & when I executes your script without the preceding "ksh -v",
it gave the same error.  Do I need to be in ksh to run your script?  Or you can make it
run even in Bourne/sh ?
0
 

Author Comment

by:sunhux
ID: 33693471

Sentner's script works fine in Bourne/sh : I'm sure I was in Bourne earlier in the HP-UX box.


   Btw, one side-question :
   Previously I enter at command prompt
/path/a_processing_shell_script S1234567H
   so I'm now placing this command in the script with the value S1234567H
   being input into the variable being read, so do we code it as follows :
/path/a_processing_shell_script  $idnum

Appreciate your help to verify if the syntax is correct
0
Highfive Gives IT Their Time Back

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 14

Expert Comment

by:sentner
ID: 33693593
If you want to make the value an argument, just remove the "read TEXT" line, and set it to something like:

if [ -z "$1" ]; then
   echo "Usage: $0 <idnum>"
   exit 1
fi

TEXT=$1
   
0
 

Author Comment

by:sunhux
ID: 33693683

To ensure I understood this, so the revised code will be as follows:


#!/bin/ksh

TEXT=""

while [ -z "$TEXT" ]; do
   printf "Enter text: "
   # read TEXT - comment this line & replace with the next 6 lines
   if [ -z "$1" ]; then
      echo "Usage: $0 <idnum>"
      exit 1
   fi

  TEXT=$1

   echo $TEXT | awk '{
      l=length($0)
      if (l<8 || l>9)
         print "Length must be 8 or 9 characters"
      else
         if (match ($0,"^[sS]"))
            if (match($0,"^[sS][0-9]+[0-9a-zA-Z]$")) {
               exit(0)
            }
            else
               print "Invalid or corrupt character has been entered"
         else
            print "Must start with S"
      exit(255)
      }' || TEXT=""
done

/path/a_processing_shell_script  $TEXT
0
 

Author Comment

by:sunhux
ID: 33693703

Forgot about converting everything to upper case, so the last few lines of the codes for the last
revised codes should read as :

. . . . .
done
typeset -u TEXT
/path/a_processing_shell_script  $TEXT
0
 
LVL 14

Assisted Solution

by:sentner
sentner earned 380 total points
ID: 33693837
Ah, I misunderstood your requirement.  The revision that I suggested was for being able to pass the "TEXT" as a command line argument to this script.  Just add the line at the end to my original version, and you'll be good.
0
 
LVL 31

Expert Comment

by:farzanj
ID: 33693897
Hi Sunhux,

My script is pure Korn shell.  It would not work on Borne.  It may not even work on Ksh 87, I am not sure.  It is using the power of Ksh regular expressions that most Korn shells have, especially all after 1993.  In your question you mentioned /bin/ksh, so I thought that was what you wanted.  I had tested my script and it was working for me on ksh.


0
 

Author Comment

by:sunhux
ID: 33701462

I think I clicked wrongly,  I meant to award the points to the experts
for providing excellent solutions
0
 
LVL 31

Expert Comment

by:farzanj
ID: 33701545
As per author's last comment, I am objecting to help him reopen this because he wanted to award points and accidentally clicked it to close.  No other objection.
0
 

Author Comment

by:sunhux
ID: 33706691

I've re-awarded again the points so we'll wait for 4 days
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Background Still having to process all these year-end "csv" files received from all these sources (including Government entities), sometimes we have the need to examine the contents due to data error, etc... As a "Unix" shop, our only readily …
Active Directory replication delay is the cause to many problems.  Here is a super easy script to force Active Directory replication to all sites with by using an elevated PowerShell command prompt, and a tool to verify your changes.
Learn several ways to interact with files and get file information from the bash shell. ls lists the contents of a directory: Using the -a flag displays hidden files: Using the -l flag formats the output in a long list: The file command gives us mor…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now