Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

shell script to ssh and find process running

Posted on 2011-05-12
20
Medium Priority
?
831 Views
Last Modified: 2012-05-11
Wondering what is the easy and quick way to find if a script is running in several unix/solaris box by ssh and find if running or not. Then email using mailx

There are alteast 10 unix / solaris box 5.10
I want shh as some "user_id" and host name with password hard-coded to 10 different severs , so that there wont be any interaction to type password.

Then find like ps -eaf | grep " xyz" or some other command to show that script xyz is not running.
Then email using Mailx or any utility saying that the script not running along with results of the command...
0
Comment
Question by:pal2k
  • 12
  • 6
  • 2
20 Comments
 
LVL 8

Expert Comment

by:point_pleasant
ID: 35749543
ssh without exchanging keys will always require a password there is no command line option to passit.
keys are easy to set up.  You could try setpass if its on your machine
0
 

Author Comment

by:pal2k
ID: 35749580
we dont have option of setting the keys.

Is that something I can create a password file and pass password to the script in order with host name in a for loop?...I saw this online...wondering how to make it work.

=======================================================
#!/bin/sh
#

stty -echo;
read -p "Input password:" A;
stty echo;
echo;

for HOST in  10.1.0.2 10.1.0.3 10.1.0.4 10.1.0.5 10.1.0.6 10.1.0.7 10.1.0.8 10.1.0.9 10.1.0.10 10.1.0.11\
 10.1.0.12 10.1.0.13 10.1.0.14 10.1.0.15 10.1.0.16 10.1.0.17 10.1.0.18 10.1.0.19 10.1.0.20 10.1.0.21\
 10.1.0.22 10.1.0.23 10.1.0.24 10.1.0.25 10.1.0.26 10.1.0.27 10.1.0.28 10.1.0.29 10.1.0.30 10.1.0.31\
 10.1.0.32 10.1.0.33 10.1.0.34 10.1.0.35 10.1.0.36 10.1.0.37 10.1.0.38 10.1.0.39 10.1.0.40 10.1.0.41\
 10.1.0.42 10.1.0.43 10.1.0.44 10.1.0.45 10.1.0.46 10.1.0.47 10.1.0.48 10.1.0.49 10.1.0.50 10.1.0.51\
 10.1.0.52 10.1.0.53 10.1.0.54 10.1.0.55 10.1.0.56 10.1.0.57 10.1.0.58 10.1.0.59 10.1.0.60 10.1.0.61\
 10.1.0.62 10.1.0.63 10.1.0.64 10.1.0.65 10.1.0.66 10.1.0.67 10.1.0.68 10.1.0.69 10.1.0.70 10.1.0.71\
 10.1.0.72 10.1.0.73 10.1.0.74 10.1.0.75 10.1.0.76 10.1.0.77 10.1.0.78 10.1.0.79 10.1.0.80 10.1.0.81\
 10.1.0.82 10.1.0.83 10.1.0.84 10.1.0.85 10.1.0.86 10.1.0.87 10.1.0.88 10.1.0.89 10.1.0.90 10.1.0.91\
 10.1.0.92 10.1.0.93 10.1.0.94 10.1.0.95 10.1.0.96 10.1.0.97 10.1.0.98 10.1.0.99 10.1.0.100 10.1.0.101
do

echo "Connecting to $HOST"
expect -c "set timeout -1;\
spawn ssh $HOST -l root \"whoami;apt-get update;apt-get upgrade;\";\
match_max 100000;\
expect *password:*;\
send -- $A\r;\
interact;"
echo "Finished job on $HOST"

done
==========================================================================
0
 

Author Comment

by:pal2k
ID: 35749793
the username and passwd is same for all servers
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:pal2k
ID: 35749878
1) ssh each host with same username & passwd

2) do something like  ps -eaf | xyz.sh | wc -l ; usually it throws the grep itself if no process running for xyz.sh

3) if count is 1 ; then may be we can print as " not running" and send the message in mailx along with server name , script name ; message (as not running if count is 1 and running if count > 1)

please advice and would appreciate a code if any better way to approach..
0
 
LVL 8

Expert Comment

by:point_pleasant
ID: 35749980
What error message do you get?

0
 

Author Comment

by:pal2k
ID: 35750337
Its just my way of approach...I dont have a code yet.....

Wondering if I can get help on code to put together....
0
 
LVL 20

Expert Comment

by:simon3270
ID: 35753049
I moved the expect script around a little, to give this:

#!/bin/sh

CMD=desired_command
USER=root
PASS=root_password

for HOST in host1.example.com host2.example.com 10.2.3.1 10.2.3.2
do
num=$(expect -c "
set timeout 30;
spawn ssh $HOST -l $USER \"ps -eaf|grep $CMD|wc -l\"
match_max 100000;
expect sword:
send -- \"$PASS\r\";
expect \"\$ \"" | tr -d '\r' | tail -1)

if [ $(echo $num | tr -d '[0-9]' | wc -c) -eq 1 ]
then
  # "ps" command worked - give result
  if [ $num -eq 2 ]
  then
    echo Command $CMD not running on host $HOST
  else
    echo Command $CMD is running on host $HOST $(expr $num - 2) times
  fi
else
  # "ps command didn't run - assume that the login failed
  echo Login to host $HOST failed
fi

done

Open in new window


The script logs into each HOST in turn, using the supplied USER name and PASSword.  It greps for $CMD in the output of "ps -eaf" and counts the number of times it finds it.  Note that because of the way ssh works, the "grep" command appears in two processes, so the returned number will be at least 2.  If it is greater than 2, then num-2 processes are running.  If the returned value (the last line of the output of the "expect" command) contains only digits, then the login and the "ps" command worked.  If it contains any non-digits, then either the login or the ps failed - I report this as a login failure.

This writes to the screen, so to finish off the script for your purposes, change the last line to be "done > ps_check.log", and use your local mail program (mailx?) to mail the contents of ps_check.log.
0
 

Author Comment

by:pal2k
ID: 35761745
Thanks Simon . I appreciate it !!  Just couple of queries....

CMD=desired_command ; can I place the script name which I need to grep  to find it is running or not?

AND

It would be nice if you can help adding mailx to send email for  alert as  I would be scheduling in cron.
with subject  "something"  and a file output attached in mailx alert which will have the list of results for below

 echo Command $CMD not running on host $HOST
   echo Command $CMD is running on host $HOST $(expr $num - 2) times
  echo Login to host $HOST failed

0
 
LVL 20

Expert Comment

by:simon3270
ID: 35763694
Yes = it's not really a "command", it's just the string your are searching for.

For mailx, just cange the "done" line as I suggest, and have:

    mailx -s "ps check on hosts" fred@example.com < ps_check.log
   
0
 

Author Comment

by:pal2k
ID: 35764485
Thanks....

Actually I need to make sure if the specifid script is" not running" , so when we gresp it should only one count right? as the grep itself returns one and nothing else should be running.

pls advice.
0
 
LVL 20

Expert Comment

by:simon3270
ID: 35765027
The grep will return 2 ifs the script is *not* running (the ssh command has one process to run the ssh interaction, and another child of that to run the sub-processes - both of these containthe full command line including the "grep" section).

One of the return values is already "Command $CMD not running on host $HOST" if the process isn't running- isn't that the one you want?  If you *only* want to report that it isn't running, change the if seciotn to be:

if [ $(echo $num | tr -d '[0-9]' | wc -c) -eq 1 ]
then
  # "ps" command worked - give result
  if [ $num -eq 2 ]
  then
    echo Command $CMD not running on host $HOST
  fi
fi
0
 

Author Comment

by:pal2k
ID: 35765326
1) wondering Is there a way in mail subject we can represent like below so that we dont have to open the attachment every time.

" script not running" when it is actually not running with the results from log
and
" script is  running" when it is actually running with the results from log

2)  Also wondering will the log will just have the message if it is running and not running or it will also have the grep results as well.

0
 
LVL 20

Expert Comment

by:simon3270
ID: 35768070
Ah, I see - you want a separate email for each host - my script sends the results for all of the hosts in a single email.

The script below will do what I think you want.  It sends an email where the subject says whether or not the command was running on a particular host, and if so, how many times.  It also sends an email if the login fails.
#!/bin/sh

CMD=desired_command
USER=root
PASS=root_password

for HOST in host1.example.com host2.example.com 10.2.3.1 10.2.3.2
do
num=$(expect -c "
set timeout 30;
spawn ssh $HOST -l $USER \"ps -eaf|grep $CMD|wc -l\"
match_max 100000;
expect sword:
send -- \"$PASS\r\";
expect \"\$ \"" | tr -d '\r' | tail -1)

if [ $(echo $num | tr -d '[0-9]' | wc -c) -eq 1 ]
then
  # "ps" command worked - give result
  if [ $num -eq 2 ]
  then
    mailx -s "Command $CMD not running on host $HOST" joe@example.com </dev/null
  else
    mailx -s "Command $CMD is running on host $HOST $(expr $num - 2) times" joe@example.com </dev/null
  fi
else
  # "ps command didn't run - assume that the login failed
  mailx -s "Login to host $HOST failed" joe@example.com </dev/null
fi

done

Open in new window


The body of the above emails will be empty - the information will all be in the subject line.  None of the scripts so far will know the details for the grep command - they all just return the number of lines in the grep output.  Do you want to see what the grep output looked like?
0
 

Author Comment

by:pal2k
ID: 35770362
Thanks  a lot !! awesome !! One more help..

I think I did not state my purpose clearly. Sorry about that. What I need is  a new  log created every time when the script runs with time stamp on the log name and in mailx email  I need the log attached along with the message on the subject in the email. So that the message will be right on the email subject and if needed we can open the log to verify if it is correct with the log results.

I appreceate it ..Simon ..
0
 

Author Comment

by:pal2k
ID: 35770385
Yes please , grep output and the count as well in the log please..thanks
0
 

Author Comment

by:pal2k
ID: 35770717
Also, I would appreciate if I can get a stand alone script like when already logged into the server and just

execute the ps -eaf | grep <script_name> > *.log and ps -eaf | grep <script_name> | wc -l  >  *.log ;

everything else stays same as above....
0
 

Author Comment

by:pal2k
ID: 35770901
Simon..

PLEASE IGNORE above 2 coments..Sorry for the confusion.....I want to make it simple....

so I came up with something like below...Would appreciate if you can help on this please....
==================================================================================
#!/bin/sh

SCRIPT=abc.sh
HOST=host_name
USER=joe


echo "Host Name $HOST User as $USER" > xyz.log_new_time_stamp
echo "" >> xyz.log_new_time_stamp
echo "Checking if the $SCRIPT is running" >> xyz.log_new_time_stamp
ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh >> xyz.log_new_time_stamp
echo"" >> xyz.log_new_time_stamp

#I want this below CMD command result to be in log before if condition.
CMD=ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh | wc -l >> xyz.log_new_time_stamp
echo ""

if [$CMD -eq 1 ]
then
    echo Command $SCRIPT not running on host $HOST as $USER
    mailx -s "$SCRIPT not running on host $HOST as $USER" joe@example.com </dev/null
    # when I send the mailx I need to attach the log file as well along with subject message.
  else
    echo Command $SCRIPT is running on host $HOST as $USER
    mailx -s "$SCRIPT not running on host $HOST as $USER" joe@example.com </dev/null
    # when I send the mailx I need to attach the log file as well along with subject message.
fi

done

============================================================================
NOTE:
1) Please help on creating log file with time stamp each time we run the script.
2) While attaching the mailx we need a command to pick the latest time stamp log.
3) Also please make necessary corrections or to improvise the script if anything needed.

Thanks Simon
0
 

Author Comment

by:pal2k
ID: 35771165
Simon,

Updated for above script little bit ; so this my final version....please look this..

!/bin/sh

SCRIPT=abc
HOST=host_name
USER=joe

echo "Host Name $HOST User as $USER" > xyz.log_new_time_stamp
echo "" >> xyz.log_new_time_stamp
echo "Checking if the $SCRIPT is running" >> xyz.log_new_time_stamp
ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh >> xyz.log_new_time_stamp
echo"" >> xyz.log_new_time_stamp
echo "ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh | wc -l" >> xyz.log_new_time_stamp

ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh | wc -l >> xyz.log_new_time_stamp
CMD=`ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh | wc -l`
echo ""

if [$CMD -eq 1 ]
then
    echo Script $SCRIPT not running on host $HOST as $USER >> xyz.log_new_time_stamp
    mailx -s "Script $SCRIPT not running on host $HOST as $USER" joe@example.com </dev/null
    # when I send the mailx I need to attach the log file as well along with subject message.
  else
    echo Script $SCRIPT is running on host $HOST as $USER >> xyz.log_new_time_stamp
    mailx -s "Script $SCRIPT not running on host $HOST as $USER" joe@example.com </dev/null
    # when I send the mailx I need to attach the log file as well along with subject message.
fi
exit 0

NOTE:
1) Please help on creating log file with time stamp each time we run the script.
2) While attaching the mailx we need a command to pick the latest time stamp log.
3) Also please make necessary corrections or to improvise the script if anything needed.
0
 
LVL 20

Accepted Solution

by:
simon3270 earned 2000 total points
ID: 35773189
I'm now confused about where you run this script, and what you actually want it to do.

The original script was run in one central server, and it reached out to each host in turn and worked out whether the particular program you wanted was running.  It then produced a single email report, listing the status of the program oneach of the hosts.

The script then changed a bit, so that it still ran on a central server, but it reported indivdually on each host, and produced an email for that host saying whether the program was running or not in the subject line.  You asked for a log to be sent, but there was no log - the only information we had was the number of processes running.

Now the script has lost the "reaching out to the hosts" code, and seems to be checking whether the program is running on the machine where you are running the script, for that single host.

If that's what you want, then the script should be:
#!/bin/sh

SCRIPT=abc
HOST=$(hostname)
USER=joe

LOGFILE=xyz_$(date '+%Y%m%d_%H%M%S').log
TMPFILE=/tmp/xyz.$$

echo "Host Name $HOST User as $USER" > $LOGFILE
echo "" >> $LOGFILE
echo "Checking if the $SCRIPT is running" >> $LOGFILE
ps -eaf|grep fwroc|grep start_neo_sdv_log_comps.sh > $TMPFILE
cat $TMPFILE >> $LOGFILE
echo"" >> $LOGFILE
CMD=`wc -l < $TMPFILE`
echo $CMD >> $LOGFILE
echo ""
rm $TMPFILE

if [ $CMD -eq 1 ]
then
    echo Script $SCRIPT not running on host $HOST as $USER >> $LOGFILE
    mailx -s "Script $SCRIPT not running on host $HOST as $USER" joe@example.com <$LOGFILE
  else
    echo Script $SCRIPT is running on $(expr $CMD - 1) times host $HOST as $USER >> $LOGFILE
    mailx -s "Script $SCRIPT not running on host $HOST as $USER" joe@example.com <$LOGFILE
fi
exit 0

Open in new window


Note that you aren't actually using the $SCRIPT variable to check for a running process.  Did you want the ps lines to be, for example:

      ps -eaf|grep fwroc|grep $SCRIPT

I've cut down the number of ps commands you run.  I ran it once to get the matching lines into a temporary file, than added the contents of that file to the log file, and did a "wc -l" on the file to count the number of processes.

You must have spaces around the "[" and "]" on the "if" line (you didn't have one after the "[").

You add the log file as the body of the email by using it as standard input, rather than /dev/null.  Note that it will be the mesage body - it won't appear as an attachment.

Also, since you are runnign the "ps" command on this machine, there will only be one instance of the "grep" line, so the "if" test shoudl be against 1, as you have it, rather than the 2 we needed when ssh was being used.
0
 
LVL 20

Expert Comment

by:simon3270
ID: 35773208
I missed out the "timestamp within the log file" bit.

Just add

    echo $LOGFILE >> $LOGFILE

to write the logfile name (which includes the timespamp) into the file.  Replace line 11 with this.
0

Featured Post

How to Use the Help Bell

Need to boost the visibility of your question for solutions? Use the Experts Exchange Help Bell to confirm priority levels and contact subject-matter experts for question attention.  Check out this how-to article for more information.

Question has a verified solution.

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

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 …
Recently, an awarded photographer, Selina De Maeyer (http://www.selinademaeyer.com/), completed a photo shoot of a beautiful event (http://www.sintjacobantwerpen.be/verslag-en-fotoreportage-van-de-sacramentsprocessie-door-antwerpen#thumbnails) in An…
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…

810 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