Solved

Unix Shell script with input validation

Posted on 2010-09-15
19
2,408 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

 

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

On Demand Webinar: Networking for the Cloud Era

Did you know SD-WANs can improve network connectivity? Check out this webinar to learn how an SD-WAN simplified, one-click tool can help you migrate and manage data in the cloud.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This Windows batch file is useful for organizing image files from a digital camera or other source, but can have many other uses.  It simply renames the file(s) to match their create date.  For example, if you took a picture today at 1:40pm and the …
The following is a collection of cases for strange behaviour when using advanced techniques in DOS batch files. You should have some basic experience in batch "programming", as I'm assuming some knowledge and not further explain the basics. For some…
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…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

729 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