Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2672
  • Last Modified:

Unix Shell script with input validation


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
sunhux
Asked:
sunhux
  • 7
  • 5
  • 4
4 Solutions
 
sentnerCommented:
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
 
farzanjCommented:
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
 
sentnerCommented:
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: Subnet Calculator

The subnet calculator helps you design networks by taking an IP address and network mask and returning information such as network, broadcast address, and host range.

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

 
sunhuxAuthor Commented:

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
 
farzanjCommented:
What version of Korn shell do you have in your system?  Korn 87?
0
 
sentnerCommented:
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
 
sunhuxAuthor Commented:

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
 
sunhuxAuthor Commented:

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
 
sentnerCommented:
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
 
sunhuxAuthor Commented:

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
 
sunhuxAuthor Commented:

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
 
sentnerCommented:
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
 
farzanjCommented:
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
 
sunhuxAuthor Commented:

I think I clicked wrongly,  I meant to award the points to the experts
for providing excellent solutions
0
 
farzanjCommented:
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
 
sunhuxAuthor Commented:

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

Featured Post

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

  • 7
  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now