1827882 Members
1208 Online
109969 Solutions
New Discussion

Script input

 
SOLVED
Go to solution
Charles Keyser
Frequent Advisor

Script input

I have a script that was written in a previous thread. We are using the Help Desk to reset and enable accounts can some help me update this I seem to have a brain cramp. Here is the script. Any help would be greatly appreciated.

#!/usr/bin/sh
#
#
#
trap '' INT
function cont
{
print -n "Do You Wish to Continue Y/N : "
read answ
if [[ $answ = [Yy] ]]
then
return 0
else
return 1
fi
}
while true
do
clear
print -n "
* HELP DESK MENU *
$(uname -n)
HELLO: $(whoami)
===================================================
1. Run Restricted SAM to reset passwords.

2. Display printer status / print jobs.
a. Enter lpstat -p to view all printers
b. Enter lpstat -o to view all print request

3. Cancel a print job.

4. Cancel ALL print jobs for a printer.

5. EXIT this program and RETURN TO COMMAND LINE.

6. Reset users passwords

7. Enable users account

===================================================

Select an Option # from above: "

read answer
case "$answer" in
5*|Qq|bye|Ee ) print "Quitting! See You Later, $(whoami)" ; exit ;;
1) if cont
then
. /usr/sbin/sam
fi;;
2) if (( $? == 0 ))
then
print -n "Enter Printer Name: "
read prtr
lpstat $prtr
print -n "OK to clear screen [Hit Any Key]"
read h
fi;;
3) if (( $? == 0 ))
then
print -n "Enter Printer Name-job#: "
read prtr
cancel $prtr
fi;;
4) if (( $? == 0 ))
then
print -n "..Enter printer name :"
read prtr_name
print -n "You enter printer ${prtr_name}"
print -n " Is this correct Y/N "
read answ
if [[ "$answ" = [Yy] ]]
then
lpstat $prtr_name | grep $prtr_name | sort -k1 | cut -d " " -f1 > $prtr_name.out
for rem_prt in `cat $prtr_name.out`
do
cancel $rem_prt
done
else
echo "No Such Printer"
fi



fi;;
esac
done




27 REPLIES 27
James R. Ferguson
Acclaimed Contributor
Solution

Re: Script input

Hi Charles:

So your question is?

A search might point you to this thread:

http://forums11.itrc.hp.com/service/forums/questionanswer.do?admit=109447626+1218120768120+28353475&threadId=1029835

Regards!

...JRF...
Charles Keyser
Frequent Advisor

Re: Script input

Sorry I really have a brain cramp. What I would like to do is have 6 an 7 executed by the help desk.
When the select 6 I would like for a question to come up and ask "enter user ID"
once that happens it should generate an for a system generated password. Once completed the help desk will have the number, call the user and provide them the information. The user then should be able to log on enter this and change their password. The other number 7 is pretty much the same enables and resets their password

I hope this helps.
Chris Vail
Honored Contributor

Re: Script input

Usually I structure these things differently. I start by putting them in a 'while true' loop. This means that no matter what the user does, the menu script always loops. But include an exit option
while true
do
......your script

x|X) exit;;
done

Also, on every case....esac menu, I usually add an * to the end. So that if the user pressess anything except a valid key, s/he will get an error message.
while true
do
case $CHOICE in
1) (do something);;
2) (do something);;
x|X) exit;;
*) echo "Invalid selection! Press [ENTER] to continue! \c"; echo "\007";read NOTHING;;
esac
done


Chris
Charles Keyser
Frequent Advisor

Re: Script input

Chris

I guess I am a little confused. Maybe a lot today then others.

while true
do

Is added at the beginning of my script?

SO if I add a line for number 6

6) if cont
then print -n "Enter users ID"

THIS is where I get hung up I have tried
usr/lbin/modprpw -x $myUserAcctName
/usr/lbin/modprpw -l -k -m
rstrpw=YES,exptm=45,nullpw=NO $myUserAcctName

It just does not seem to work. Am I adding this incorrectly? I wil be running this script on 3 servers 2 are 10.20's the other is 11.00
It has been awhile since I have written scripts. A long while. Any advice or input is greatly appreciated.

Thank you again for your time and patience

-Charlie
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi (again):

> once that happens it should generate an for a system generated password. Once completed the help desk will have the number, call the user and provide them the information. The user then should be able to log on enter this and change their password. The other number 7 is pretty much the same enables and resets their password

OK, if you want a random, clear-text password, use the Perl script I wrote here:

http://forums11.itrc.hp.com/service/forums/questionanswer.do?threadId=1231878

If you want an encrypted, random password use my variation here:

http://forums11.itrc.hp.com/service/forums/questionanswer.do?threadId=1252591

I also agree with Chris: for menu-based scripts, a 'while true do;' loop with an 'continue', 'break' and 'exit' controls works very well.

Regards!

...JRF...
Chris Vail
Honored Contributor

Re: Script input

>Chris
>I guess I am a little confused. Maybe a lot today then others.

I spend a lot of my life confused. You're not alone!

>while true
>do

>Is added at the beginning of my script?

Yes. The final 'done' is at the end of the script.

>SO if I add a line for number 6
>6) if cont
>then print -n "Enter users ID"

>THIS is where I get hung up I have tried
>usr/lbin/modprpw -x $myUserAcctName
>/usr/lbin/modprpw -l -k -m
>strpw=YES,exptm=45,nullpw=NO >$myUserAcctName

>It just does not seem to work. Am I adding this incorrectly? I wil be running this script on 3 servers 2 are 10.20's the other is 11.00
>It has been awhile since I have written scripts. A long while. Any advice or input is greatly appreciated.

Inside your case...esac statement you have already done most of your if/then logic. I would structure item 6 like this:
6) echo "Username to modify \c"; read USER
TESTNAME=`grep $USER /etc/passwd|awk -F: '{ print $1 }'`
if test "$USER" != "$TESTUSER"
then
echo "$USER is invalid!"
else
passwd $USER
fi;;

This snippet takes input from the operator, and compares it against the password database. It runs the password command if it matches, and echos an error code if it doesn't.

Because it is in a 'while true ' loop, the menu will display again and it can be chosen again.

>Thank you again for your time and patience

The best way to say 'thanks' is to assign points!


Chris
Charles Keyser
Frequent Advisor

Re: Script input

Thanks again. I have added your logic to the script when I select the menu number

6. Reset User Passwords

I receive a prompt

Username to modify

I eneter a user ada0160 who's account is locked

and I even enter mine cjk1402 to change my password it loops back to the main screen not allow any changes. I do see invalid user flash really quick

Again Thank you for your input.



Chris Vail
Honored Contributor

Re: Script input

Yes, I did leave something out of that previous snippet. Here I will correct it:

6) echo "Username to modify \c"; read USER
TESTNAME=`grep $USER /etc/passwd|awk -F: '{ print $1 }'`
if test "$USER" != "$TESTUSER"
then
echo "$USER is invalid!"
echo "Press [ENTER] to continue. \c"
read NOTHING
else
passwd $USER
fi;;
Charles Keyser
Frequent Advisor

Re: Script input

Chris

I finally realized that I did not select the drop menu for the points. I have set your reply s to 10. You have been very helpful.

-Charlie
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi (again):

You can/should reward points to all respondents of your thread to the degree that you feel they helped you:

http://forums11.itrc.hp.com/service/forums/helptips.do?#28

Regards!

...JRF...
Charles Keyser
Frequent Advisor

Re: Script input

JRH

My apologies to you. I did add points to yours also and failed to acknowledge that

Chris

Maybe I am missing something here or my skills are just lacking I made the changes as you sent
here is what I receive now

select option for password reset

Username to modify cjk1402
cjk1402 is invalid!
Press [ENTER] to continue

Since I am a user why would I receive the the invalid user?

I did a cat on /etc/passwd and my user id is there.

-Charlie
Chris Vail
Honored Contributor

Re: Script input

Instead of 'cat-ing' /etc/passwd, try grep'ing it with the following:

grep $USER /etc/passwd|awk -F: '{ print $1 }'

The grep command matches the input string $USER with any entry in /etc/passwd. The awk portion of the command sets the colon (:) as the field delimiter and then prints the first field in the returned line.

So the grep command might return something like:

user1:WSzIkVWhiLvCM:1154:20::/users/user1:/bin/ksh

The first field is the username. Then comes the encrpyted password (unless you are using a trusted system) then the user number (UID), then the group ID (GID), then the home directory for user1, and the last field is the shell that user1 will use on login. You are interested ONLY in the first field.

So try this experiment......
First use grep to find your user ID. It must be an exact match or it won't work.
Then try the grep command in combination with the awk command I printed above. If the grep command worked, then the awk command should also.

It is possible to do the entire line with a single awk command, but I use grep as a matter of habit.

Chris
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi (again) Charlie:

Chris's code mixes variable names -- TESTUSER and TESTNAME -- and they are not the same!

Try this:

#!/usr/bin/sh
set -u
echo "Username to modify \c"; read USER
TESTUSER=`awk -v USER=${USER} -F: '$1~USER { print $1 }' /etc/passwd`
if test "$USER" != "$TESTUSER"
then
echo "$USER is invalid!"
echo "Press [ENTER] to continue. \c"
read NOTHING
else
echo $USER
fi

...

Note that I added 'set -u' to the script to catch undefined (empty) variables. This makes debugging so much easier!

Note too that I removed a 'grep'/'awk' pipeline. Awk pattern matches and the 'grep' process is wasteful.

Regards!

...JRF...
Charles Keyser
Frequent Advisor

Re: Script input

JRF

here is the complete script with changes. I ran it and it still says, maybe I have typed something incorrectly? -Charlie

Select an Option # from above: 5
Username to modify cjk1402
cjk1402 is invalid!
Press [ENTER] to continue.

Here is what I have done from the command line to verify if I am in the passwd file


grep cjk1402 /etc/passwd|awk -F: '{ print $1 }'

here is the return

cjk1402


++++++++++++++++++++++++++++++++++++++++++++

trap '' INT
function cont
{
print -n "Do You Wish to Continue Y/N : "
read answ
if [[ $answ = [Yy] ]]
then
return 0
else
return 1
fi
}
while true
do
clear
print -n "
* HELP DESK MENU *
$(uname -n)
HELLO: $(whoami)
===================================================
1. Run Restricted SAM to reset passwords.

2. Display printer status / print jobs.
a. Enter lpstat -p to view all printers
b. Enter lpstat -o to view all print request

3. Cancel a print job.

4. Cancel ALL print jobs for a printer.

5. Reset User Passwords

6. EXIT this program and RETURN TO COMMAND LINE.


===================================================

Select an Option # from above: "

read answer
case "$answer" in
6*|Qq|bye|Ee ) print "Quitting! See You Later, $(whoami)" ; exit ;;
1) if cont
then
. /usr/sbin/sam
fi;;
2) if (( $? == 0 ))
then
print -n "Enter Printer Name: "
read prtr
lpstat $prtr
print -n "OK to clear screen [Hit Any Key]"
read h
fi;;
3) if (( $? == 0 ))
then
print -n "Enter Printer Name-job#: "
read prtr
cancel $prtr
fi;;
5) echo "Username to modify \c"; read USER
TESTNAME=`awk -v USER=${USER} -F: '$1~USER { print $1 }' /etc/passwd`
if test "$USER" != "$TESTUSER"
then
echo "$USER is invalid!"
echo "Press [ENTER] to continue. \c"
read NOTHING
else
echo $USER
fi;;
4) if (( $? == 0 ))
then
print -n "..Enter printer name :"
read prtr_name
print -n "You enter printer ${prtr_name}"
print -n " Is this correct Y/N "
read answ
if [[ "$answ" = [Yy] ]]
then
lpstat $prtr_name | grep $prtr_name | sort -k1 | cut -d " " -f1 > $prtr_name.out
for rem_prt in `cat $prtr_name.out`
do
cancel $rem_prt
done
else
echo "No Such Printer"
fi



fi;;
esac
done
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi (again) Charles:

Ah, regarding you last post. Put the following two lines at the top of your script and run it again :-)

#!/usr/bin/sh
set -u
...

The first line is good practice -- to declare the interpreter you want to use. It avoids ambiguity.

The second line exposes your error.

Select an Option # from above: 5
Username to modify xxx
/tmp/0807[65]: TESTUSER: Parameter not set.

Once again, you have TESTUSER and TESTNAME:

# grep TEST /tmp/0807
TESTNAME=`awk -v USER=${USER} -F: '$1~USER { print $1 }' /etc/passwd`
if test "$USER" != "$TESTUSER"

...consistency counts :-)

Regards!

...JRF...
Steven E. Protter
Exalted Contributor

Re: Script input

Shalom,

I find set -x is useful as well in spotting scripting errors.

Your last mistake is merely from experience and requires you merely to become familiar with the tools in this thread and use them in future scripting work.

Very interesting thread BTW.

Good luck with your debug.

SEP
Steven E Protter
Owner of ISN Corporation
http://isnamerica.com
http://hpuxconsulting.com
Sponsor: http://hpux.ws
Twitter: http://twitter.com/hpuxlinux
Founder http://newdatacloud.com
Charles Keyser
Frequent Advisor

Re: Script input

Steven Thanks for your input

JHR

Well I guess I am lost at this point. Trying to be constant

Do I need to replace the TESTNAME with TEST USER?
Do I need to create this id. I guess I need to go back to the books and read. Good thing I have 3 months to have this written and ready.

Thanks

-Charlie



James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi Charlies:

> Do I need to replace the TESTNAME with TEST USER?

Chose either name for your variable --- TESTNAME or TESTUSER. If it was up to me, I'd use "TESTUSER" since you are comparing the value of ${TESTUSER} to ${USER}:

#!/usr/bin/sh
set -u
echo "Username to modify \c"; read USER
TESTUSER=`awk -v USER=${USER} -F: '$1~USER { print $1 }' /etc/passwd`
if test "${USER}" != "${TESTUSER}"
then
echo "${USER} is invalid!"
echo "Press [ENTER] to continue. \c"
read NOTHING
else
echo ${USER}
fi

...note that for good standards, I enclosed the variables in curly braces when I wanted to evaluate their value. This is a good habit, in my opinion, to form, although it isn't required unless you do:

# USER=charlie
# PASS=hisword
# echo $USER_$PASS
sh: USER_: Parameter not set.
# echo ${USER}_${PASS}
charlie_hisword

Regards!

...JRF...
Charles Keyser
Frequent Advisor

Re: Script input

JRF

Added everything ran it, was able to scroll up and see the results. no errors

Now once this is done, and ran, I want to have it prompt me to change password or reset account would after the last line (see below)


set -u
echo "Username to modify \c"; read USER
TESTUSER=`awk -v USER=${USER} -F: '$1~USER { print $1 }' /etc/passwd`
if test "${USER}" != "${TESTUSER}"
then
echo "${USER} is invalid!"
echo "Press [ENTER] to continue. \c"
read NOTHING
else
echo ${USER}
passwd
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi Charles:

> I want to have it prompt me to change password

OK, given that you are running as 'root', doing:

...
passwd ${USER}
...

...will prompt you at your terminal to provide a new password. You could use the 'pwgen' Perl script I offered here to create a random password for your user:

http://forums11.itrc.hp.com/service/forums/questionanswer.do?admit=109447626+1218139023853+28353475&threadId=1231878

Unfortunately, you cannot redirect input into 'passwd'. You need another method if the interactive approach doesn't suit you, and this begins to get ugly soon.

Regards!

...JRF...

Charles Keyser
Frequent Advisor

Re: Script input

This was great. I changed the line, looks like this is going to work. I was able to change my password.

The other route I am going to work on, this script will be used for our help desk, I wil need to modify the sudoers so when the help desk logs on the can run this. That is later.

Aw some knowledge transfer -Charlie

Now for a message that says password lifetime has passed (see below)

Select an Option # from above: 5

Username to modify ada0160

Last successful password change for ada0160: Tue Nov 27 10:15:27 2007
Last unsuccessful password change for ada0160: Tue Apr 17 16:26:29 2007


Password cannot be changed. Reason: password lifetime has passed.
Dennis Handly
Acclaimed Contributor

Re: Script input

>Chris: try grep'ing it with the following:
grep $USER /etc/passwd|awk -F: '{ print $1 }'

To be pedantic, you should search in awk, or grep after awk. That way you don't find substrings or a name in the home directory. Or somewhere in the full name field. Or anchor the search as below.

>user1:WSzIkVWhiLvCM:1154:20:
>It must be an exact match or it won't work.

Then you would need to anchor it to the beginning:
grep "^${USER}:" /etc/passwd

>It is possible to do the entire line with a single awk command, but I use grep as a matter of habit.

Me too but I'm learning. :-)
Chris Vail
Honored Contributor

Re: Script input

>Chris: try grep'ing it with the following:
grep $USER /etc/passwd|awk -F: '{ print $1 }'

>To be pedantic, you should search in awk,
>or grep after awk. That way you don't find >substrings or a name in the home
>directory. Or somewhere in the full name
>field. Or anchor the search as below.

>>user1:WSzIkVWhiLvCM:1154:20:
>>It must be an exact match or it won't work.

>Then you would need to anchor it to the >beginning:
>grep "^${USER}:" /etc/passwd

>>It is possible to do the entire line with
>>a single awk command, but I use grep as a
>>matter of habit.

>Me too but I'm learning. :-)

Since we are being pedantic (and good sysadmins make pedantic an art form), the proper awk script reads:

awk -F: '/'^$USER'/ { print $1 }' /etc/passwd

There, thats the one-liner that we all ascribe to.
James R. Ferguson
Acclaimed Contributor

Re: Script input

Hi (again):

Well, consider this :

# USER=operator
# awk -F: '/'^$USER'/ { print $1 }' /etc/passwd
op
#
...so this is really a failed match since the user "op" isn't the user "operator".

This solves the problem, though:

# USER=operator
# awk -v USER=${USER} -F: '$1==USER { print $1 }' /etc/passwd
#

...that is, no match is found.

Now, in fairness to this thread, the first posting I did used "$1~USER" which suffers from the same mismatch that I just corrected :-(

Regards!

...JRF...