?
Solved

Korn Shell arrays

Posted on 2003-03-21
12
Medium Priority
?
835 Views
Last Modified: 2013-12-26
Good morning all,

I have a script that I wrote this morning that I can not figure out how to finish. This script will be used to kick a user out of my application. My goal is to prompt the user for the username of the person that they wish to kick off, retain that username in a variable, load in the userid associated with that username, and then use the userid to remove them from the system. My problem is, I want to propmt the user for the username, but the only way that I can kick someone out of the application is via the userid.

I am trying to take the following output:

UID  user  The rest is really useless information for this purpose ...
365  jx5h  T00A1AD.opr.statefarm.org  ECS_GUI  03/13/03 08:41:49:389920
447  jx5h  T0093E5.opr.statefarm.org  ECS_GUI  03/17/03 18:12:23:268080
450  c8zg  T000FDA.opr.statefarm.org  ECS_GUI  03/18/03 07:18:17:484342

retrieved with the following command:

ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v Open |grep -v have |grep -v The

and feed the uid into the following command to remove them from the app:

ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr KICK $uid

Note: Currently I am printing some info to the user about the program, prompting
them for a username, and verifying that the username entered is currently logged
in to the application, and futher giving them only three attempts to enter a valid
username.

The following is what I have so far:

#!/usr/bin/ksh

logo="Remove ECS Users"

prmpt() {
clear
print "\n\t\t\t+----------------------------+"
print "\t\t\t|      ${logo}      |"
print "\t\t\t|\t - $(hostname) -\t     |"
print "\t\t\t+----------------------------+"
print "\n\n\n\n\n\tThis program will allow you to 'Kick' a user off of ECS."
print "    Please do not kick a user off of ECS without notifying them first!"
print "\n\tEnter the the userid of the person to be removed below."
print "\t        The userid will be the same as the SFID."
print "\nUserid -> \c"
read userid
}

pgui_out="/opt/incontrol/sf_scripts/admin/j8vy/pgui_rpt.txt"
euser=$(awk '{print $4}' /opt/incontrol/sf_scripts/xfile)
epass=$(awk '{print $5}' /opt/incontrol/sf_scripts/xfile)

set -A id $(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $2}')

prmpt
cnt="-1"
while [[ ${userid} != ${id} ]]; do
if [[ ${cnt} < 2 ]] && [[ ${cnt} > "-1" ]]; then
   print "\nOops ... That user is not currently logged in!"
   print "Please enter a valid userid."
   sleep 3
  prmpt
elif [[ ${cnt} = 2 ]]; then
   print "\nYou have reached the maximum number or retries!"
   print "Please try again at a later time.\n"
   exit 1
fi
 let cnt+=1
done

Your thoughts are appreciated.
P.S. I would prefer to keep this in Korn Shell if it is possible. Thanks.
0
Comment
Question by:j8vy
[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
  • 6
  • 3
  • 2
  • +1
12 Comments
 

Author Comment

by:j8vy
ID: 8179983
I am sure that I need to assign the uid to an array.

I did this for the username so that I could verify if the username being entered was a valid user.

You will notice this in my code:

set -A id $(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $2}')

I know that I can also do this for the uid,
like this:
set -A uid $(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $1}')

but my question is, how do I relate the uid and the username if they are in seperate arrays.

Thanks again.

0
 

Author Comment

by:j8vy
ID: 8180436
I also just realized that in my 'while loop' test to see if the user is currently logged in:

while [[ ${userid} != ${id} ]]; do

using:

set -A id $(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $2}')

to get the userid

The while loop is only checking the first occurrence in the 'id' array field. I.e. The output would be:

365  jx5h  T00A1AD.opr.statefarm.org  ECS_GUI  03/13/03 08:41:49:389920
447  jx5h  T0093E5.opr.statefarm.org  ECS_GUI  03/17/03 18:12:23:268080
450  c8zg  T000FDA.opr.statefarm.org  ECS_GUI  03/18/03 07:18:17:484342

and if I try user 'jx5h' the test will pass, but if I try to use 'c8zg' the test will fail every time!

I know that the 'id' array contains all of the data, but somehow I am not reading all of that data in my 'while' test.

0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8183222
Why array?

list the current users to temp file /tmp/current_users.txt
grep on this file
if grep sucess then you found it


let me know if you agree so I can give you code example
0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 2

Expert Comment

by:ellesd
ID: 8183251
I'm sure there are many ways to do it, but off the top of my head, try something similar to:
  let idx=1
  while [ "$idx" -lt "${#id[*]}" ]
  do
    if [ "$userid" == "$id[$idx]" ]
    then
      found=1
      break
    else
      found=0
      let idx=$idx+6
    fi
done
if [ "$found" -eq 0 ]
then
   kick them off
else
   try again
fi

Set idx equal to the element of the array you are checking; they start numbering at zero.  Add the number of fields in each line to idx to check the next value you are looking for; the same field in each line will have the same offset equal to the number of fields.  You should be able incorporate this into your code.  If you need more explanation, let me know.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 8184248
assuming your ecw.ctl pruduces a line like:
  365  jx5h  T00A1AD.opr.statefarm.org  ECS_GUI  03/13/03
then do following (sh syntax:
user=`ecw.ctl ... |awk '{print $2}'`
uid=awk -F: '/^'$uid'/{print $3}' /etc/passwd
0
 

Author Comment

by:j8vy
ID: 8200570
I'm sorry for the long delay in my response, but each of your post have made me start thinking.

I think that I am going to approach this from a different angle, so I may need more help with this later on. If the question varies too much, I will post a new question.

-- HamdyHassan's post made me think about the fact that I should do this differently entirely. I will ask more questions later.

Thanks.
0
 

Author Comment

by:j8vy
ID: 8202134
Thanks for everyones help with this.

I have a question that applies to this program, but I will post as a new question if so desired.

-- I need to create a multi-column output of my usernames.
I will generating the list from the following command:

$(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $2}')

which will generate something like:
j8vy
c4db
h4ds
...
...

This list will be very long at times, so I would like to display all of these usernames like:

j8vy  bdfg  g6eg
c4db  c4ka  jdse
h4ds  dsfg  dfgs
....  ....  ....
....  ....  ....

current settings are:

$COLUMNS=80
$LINES=24

and I would like to just space the columns evenly across the screen. I am thinking that maybe 20 lines and however many columns (2 spaces between) will fit. I am thinking that I should set the columns up first, then just let the lines go as long as they need to, but I am unsure of how this procedure is accomplished. There are not going to be more than 100 - 150 users on the system at anytime, so 30 lines should be more than enough.

I plan to just use the "resize" command to resize the
window to whatever size it should be to display the proper
length (however many lines we come up with)

Your thoughts are appreciated.
0
 
LVL 51

Expert Comment

by:ahoffmann
ID: 8203128
# replace you last awk with:
awk '{printf" %s",$2;x++;if(x%3==0){printf"\n"}}'
0
 
LVL 9

Accepted Solution

by:
HamdyHassan earned 400 total points
ID: 8203568
Unix offer command for this multi columns issue
"pr" command

for example
$(ecs.ctl -U $euser -P $epass -C GUI_Server -M sf40ctm1 -cmdstr PGUI |grep -v The |grep -v have |grep -v Open |awk '{print $2}')
|   pr -3    

will make three columns



take a look at man page for more details


0
 

Author Comment

by:j8vy
ID: 8204908
... and there I was sitting here looking like a dumbass, trying to make something harder than it was.

I would like to personally say thanks to everyone for their help and assistance, but I feel that I should give the points to HamdyHassan.

HamdyHassan, you have helped me before, and you have helped me here. If you will recall, I had asked you earlier not to post solutions, but to just tip me in the right direction, because my purpose of coming here is not to have you do the work, but to learn from this experience and take that knowlege with me. I believe that it has already been proven that you guys know how to do this stuff!!

Which brings me to my point, I was headed in a totally different direction when I started this program, but after reading HamdyHassan's first post the other day, I literally opened up my program in vi editor and held the 'd' key!! Yep..., I deleted the whole damn thing and started over, and the following is the result (a program that works great, impressed my teammates, and will save us time in the future:

Here is the code:
#!/usr/bin/ksh
#-----------------------------------------------------------------------------
# Program       : kick_ecsuser.ksh
# Purpose       : Print a detailed list of all users logged into ECS and then
#                 "KICK" those users out of the ECS application based on
#                 their alias.
# Contact       : Control-M Support PM
# Author      : matthew.vaden.j8vy@statefarm.com
# Dependencies      : This program has been tested on ECS ver 6.0.03 w/ the
#                 the following patches:
#                 ECS: 6.0.03; Oracle 8.1.7.4
#                 FD: 4333, 4494, & 4646
#                 It is NOT currently known to work on any higher versions,
#                 and futhermore will NOT work w/o the listed dependencies.
#            : Rc values:
#              rc=0 -> Program completed successfully
#                 rc=1 -> Incorrect userid was entered
#                 rc=2 -> "KICK" command did not execute successfully
#                 rc=3 -> User quit out of program
# Warranty      : This program comes without any warranty express or implied
#                 and is NOT part of the original install of Control-M and
#                 therefore is NOT supported by BMC software. For support
#                 with this program, please contact Control-M Support PM.
# Maintenance   :
# Date          Description
# --------      --------------------------------------------------------------
# 03/19/03      Initial testing phase and planning
# 03/25/03      Final Code development
#-----------------------------------------------------------------------------

#----------------------------------
# Step 1
# Define local vars
#----------------------------------
host=$(hostname)
logo="Remove ECS Users"
pgui_out="/opt/incontrol/sf_scripts/admin/j8vy/pgui_rpt.txt"
kick_out="/opt/incontrol/sf_scripts/admin/j8vy/kick_rpt.txt"
euser=$(awk '{print $4}' /opt/incontrol/sf_scripts/xfile)
epass=$(awk '{print $5}' /opt/incontrol/sf_scripts/xfile)

#----------------------------------
# Step 2
# Define local functions
#----------------------------------
prmpt() {
clear
print "\n\t\t\t+----------------------------+"
print "\t\t\t|      ${logo}      |"
print "\t\t\t|    ECS Server: $host    |"
print "\t\t\t+----------------------------+"
print "\n\n\n\n\n\tThis program will allow you to 'Kick' a user off of ECS."
print "    Please do not kick a user off of ECS without notifying them first!"
print " First enter your answer, then enter the sfid of the person to be removed below.\n"
}

#----------------------------------
# Step 3
# Main body
#----------------------------------
while true; do
prmpt
print "    Would you like to see a list of users currently logged in to ECS?"
print "\nEnter response (y/n/q): \c"
read ans
case ${ans} in
#----------------------------------
# Step 3b
# First step(if $ans is 'y' or 'Y')
#----------------------------------
y|Y)
    resize -s 28 80 >/dev/null
ecs.ctl -U $euser -P $epass -C GUI_Server -M ${host} -cmdstr "PGUI" |grep -v The |grep -v have |grep -v Open |awk '{print $2}' |pr -tr -7

print "\nEnter the sfid -> \c"
read userid

ecs.ctl -U $euser -P $epass -C GUI_Server -M ${host} -cmdstr "PGUI" |grep -v The |grep -v have |grep -v Open > ${pgui_out}

cat ${pgui_out} |while read line; do
    uid=$(echo ${line} |awk '{print $1}')
    sfid=$(echo ${line} |awk '{print $2}')
  if [[ ${userid} = ${sfid} ]]; then
      for id in ${uid}; do
         ecs.ctl -U $euser -P $epass -C GUI_Server -M ${host} -cmdstr "KICK ${id}" > ${kick_out}
      done
  fi
done
 if [[ -a ${kick_out} ]]; then
  cat ${kick_out} |grep not >/dev/null
    if [[ ${?} = 1 ]]; then
       print "\nThe following user has been 'kicked' out of ECS:"
       print "SFID: ${userid}"
       print "\nJust restart the program to kick off another user."
      rm -f ${pgui_out} >/dev/null
      rm -f ${kick_out} >/dev/null
      exit 0
    elif [[ ${?} = 0 ]]; then
       print "\nNo users were kicked out of ECS!"
       print "SFID: ${userid} is not currently logged in to ECS."
       print "\nHint: Choose 'y' when asked if you wish to see the users currently logged into ECS.\n"
      rm -f ${pgui_out} >/dev/null
      rm -f ${kick_out} >/dev/null
      exit 1
    fi
 else
   print "\nNo output was generated."
   print "It appears that the 'KICK' command did not execute."
   print "Please contact Control-M Support PM if problems persist."
   exit 2
 fi
break ;;

#----------------------------------
# Step 3c
# 2nd  step (if $ans is 'n' or 'N')
#----------------------------------
n|N)
    print "\nEnter the sfid -> \c"
    read userid

ecs.ctl -U $euser -P $epass -C GUI_Server -M ${host} -cmdstr "PGUI" |grep -v The |grep -v have |grep -v open > ${pgui_out}

cat ${pgui_out} |while read line; do
    uid=$(echo ${line} |awk '{print $1}')
    sfid=$(echo ${line} |awk '{print $2}')
  if [[ ${userid} = ${sfid} ]]; then
      for id in ${uid}; do
         ecs.ctl -U $euser -P $epass -C GUI_Server -M ${host} -cmdstr "KICK ${id}" > ${kick_out}
      done
  fi
done
 if [[ -a ${kick_out} ]]; then
  cat ${kick_out} |grep not >/dev/null
    if [[ ${?} = 1 ]]; then
       print "\nThe following user has been 'kicked' out of ECS:"
       print "SFID: ${userid}"
       print "\nJust restart the program to kick off another user."
      rm -f ${pgui_out} >/dev/null
      rm -f ${kick_out} >/dev/null
      exit 0
    elif [[ ${?} = 0 ]]; then
       print "\nNo users were kicked out of ECS!"
       print "SFID: ${userid} is not currently logged in to ECS."
       print "\nHint: Choose 'y' when asked if you wish to see the users currently logged into ECS.\n"
      rm -f ${pgui_out} >/dev/null
      rm -f ${kick_out} >/dev/null
      exit 1
    fi
 else
   print "\nNo output was generated."
   print "It appears that the 'KICK' command did not execute."
   print "Please contact Control-M Support PM if problems persist."
   exit 2
 fi
break ;;

q|Q)
   exit 3
   break ;;

*)
  print "\nYour answer can not be blank!"
  print "You must enter a valid user"
  print "Please try again ...\n"
  sleep 4
  ;;
esac
done
 

... thanks for the help and inspiration.
0
 

Author Comment

by:j8vy
ID: 8204922
Thanks man ... You can answer my questions anytime!
0
 
LVL 9

Expert Comment

by:HamdyHassan
ID: 8211014
wow that script looks good.  Congratualtion j8vy
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Question has a verified solution.

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

Introduction: Displaying information on the statusbar.   Continuing from the third article about sudoku.   Open the project in visual studio. Status bar – let’s display the timestamp there.  We need to get the timestamp from the document s…
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video, Percona Director of Solution Engineering Jon Tobin discusses the function and features of Percona Server for MongoDB. How Percona can help Percona can help you determine if Percona Server for MongoDB is the right solution for …
Suggested Courses
Course of the Month9 days, 21 hours left to enroll

762 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