Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

How to check running processes from an inputfile

Status
Not open for further replies.

sivhaga

IS-IT--Management
Jun 3, 2008
25
I have got an inputfile having processes names.
The file called atp.text has got two fields and looks like:

createcase createaa
createcase createbb
createcase createcc

This file has got a 85 records and we started all the processes with the following command:
{
cmd="nohup " $1 " ATP $ENVIRONMENT -sectionname " $2

system(cmd)
}

The above code starts all the processes from the above file.The challenge that im facing now is when one or more processes have stopped, how do i check if they have stopped and how to start it. How do i compare from the system and the one from my input file which one has stopped.If it has stopped i have to start it but if it is still running i have to skip it

Which code can i use on Unix or Awk. Pls pls pls I have spend 3 weeks and not winning.

Thanks in advance

 
Capture the process list to a file, something like ps -eo comm > /tmp/processes, and then read that file into your awk script, then you can check whether the process is already running before starting it.

Annihilannic.
 
Ok,i agree with the idea but i find it difficult to impelement it. What i did here i captured all the processes running on the system something like:
>out=$(ps -eaf | grep $ENVIRONMENT | grep ATP | grep sectionname| awk '{print $13}')
> echo "$out\n" > OUTPUT

Right now i have got two files called OUTPUT file(This contains all the running processes) and ATP file(This contains all the processes that have to be checked one by one, it has got two columns).

Can you please help me with the code for checking if a process is running.I mean comparing two files.

Your assistance will be highly appreciated

 
Hi Annihilannic,

So far this is what i did:
out=$(ps -eaf | grep $ENVIRONMENT | grep ATP | grep sectionname| awk '{print $2, $12}')
echo "$out\n" > OUTPUT # capture all the running proccesses from the system and redirect to the OUTFILE file
chmod +x OUTPUT # making the file executable


echo "\n######## Processes running are ####### \n "
awk 'NR==FNR { ref[$NF]; next } ($NF in ref) { printf "%s %s already started\n",$1,$NF }' OUTPUT atp

echo "\n\n######Processes not running are ##############: \n "
awk 'NR==FNR { ref[$NF]; next } !($NF in ref) { print $NF }' OUTPUT atp
# awk 'NR==FNR { ref[$NF]; next } !($NF in ref) {"nohup " $1 " ATP $ENVIRONMENT -sectionname " $2 " 1>>$SMLOGPATH/"$2".out" " 2>>$SMLOGPATH/"$2".err" " &" }' OUTPUT atp
rm OUTPUT #removing the file from the system

N.B OUTPUT and atp are the inputfile but the OUTPUT file contains all the running processes from the system.

Please help me out with the code to restart for those which are not running and skip those once which runs.

 
You've made some good progress...

For the first part, it is unnecessary to assign it to a variable and then echo it into a file, a simpler way would be:

Code:
ps -eaf | grep $ENVIRONMENT | grep ATP | grep sectionname| awk '{print $2, $12}' > OUTPUT

Also there is no need to make it executable. You are going to read the file, not execute it.

In this section you need to actually assign a value to the array, any value will do, e.g.:

Code:
awk 'NR==FNR { ref[$NF][COLOR=red]=1[/color]; next } !($NF in ref) { print $NF }' OUTPUT atp

Try that and see if it lists the processes you expect to start.

Annihilannic.
 
Hi Annihilannic,

Thanks for all your responses, I did to assign a value to the array like above(awk 'NR==FNR { ref[$NF]=1; next } !($NF in ref) { print $NF }' OUTPUT atp )but it doesnt give me anything.

Nevermind, It only works without assigning a value and lists all those processes that i expect to start.

One big question now i, as the file OUTPUT lists all the running processes on the system and would like to kill only those ones which are up from the atp file how do i write my code. I only know that i can do the Kill [process_id] , where process_id is from OUTPUT file.

How do i get only those process_id's from OUTPUT file and but only for those processes which are up from atp.

The code should be accept two input files like above.I can only be able to startup all processes by using this code:
awk 'NR==FNR { ref[$NF]; next } !($NF in ref) {nohupcmd="nohup " $1 " ATP $ENVIRONMENT -sectionname " $2 " 1>>$SMLOGPATH/"$2".out" " 2>>$SMLOGPATH/"$2".err" " &"; system(nohupcmd) }' OUTPUT atp
Your help will be highly appreciated
 
Can you show us some example contents from the OUTPUT file?

What operating system is this on?

Annihilannic.
 
Examples for OUTPUT file are:

76907 createaa
90456 script1
38789 createbb
67897 createcc
......
......
where 1st column is the process_id and 2nd column process name.

As the atp file contains all the processes that should run such as:
createcase createaa
createcase createbb
createcase createcc

And OUTPUT FILE contains all the running processes on the system, Im asking for your help on how can i kill all those processes which are running? how do i kill/stop processes just by taking the process_id from OUTPUT file?
I hope now is clear, I would really appreciate your help.
 
I just tried on AIX 5.2.0 an my code seems to work as expected with or without the =1:

[tt]$ cat atp
createcase createaa
createcase createbb
createcase createcc
$ cat OUTPUT
76907 createaa
90456 script1
38789 createbb
$ awk 'NR==FNR { ref[$NF]=1; next } !($NF in ref) { print $NF }' OUTPUT atp
createcc
$ awk 'NR==FNR { ref[$NF]; next } !($NF in ref) { print $NF }' OUTPUT atp
createcc
$[/tt]

Your version to start the process also works as expected, although I replaced system with print for testing purposes:

[tt]$ awk 'NR==FNR { ref[$NF]; next } !($NF in ref) {nohupcmd="nohup " $1 " ATP $ENVIRONMENT -sectionname " $2 " 1>>$SMLOGPATH/"$2".out" " 2>>$SMLOGPATH/"$2".err" " &"; print nohupcmd }' OUTPUT atp <
nohup createcase ATP $ENVIRONMENT -sectionname createcc 1>>$SMLOGPATH/createcc.out 2>>$SMLOGPATH/createcc.err &
$
[/tt]

This should work for killing them, note that the order of the input files is reversed:

Code:
 awk 'NR==FNR { procnames[$NF]; next } ($NF in procnames) { print $1 }' atp OUTPUT | xargs kill

Annihilannic.
 
Thanks, it is working well well fine.Thank you so much and if it wasnt you i dont know, i've learnt a lot. Also i do agree with you that it also work with/without assigning the value to an array.

Thank you so much.
 
The code is working fine,but now i have got a big challenge.Do you know how to create a submenu in AIX?


I have created a menu script having 3 main options.It works well. But I would like to have a submenus within an option.

Eg. 1.Start - ATP
- BILLING
2.Check - ATP
- BILLING
3.Kill - ATP
- BILLING
Therefore the only code that i can only Start ATP,Check ATP and Kill ATP. How do i add a submenu BILLING like if you choose to Start, then it has to display two options either you want to start ATP or BILLING.

My code so far is

while :
do
clear
echo "=================================================================================================== ===="
banner " ATP MENU"
echo " 1. Check all running processes"
echo " 2. Start all processes"
echo " 3. Kill all processes"
echo " Q. Quit"
echo "=================================================================================================== ===="
echo "Enter your menu choice [1-3 or q]: "

read userinput
case $userinput in

1) echo "Check all option selected\n\n"
CHECKATP
echo "Press any key to continue" ; read ;;
2) echo "Start all option selected\n\n"
STARTATP
echo "Press any key to continue" ; read ;;
3) echo "Kill all option selected"
echo "Press any key to continue" ; read ;;
[qQ]*) exit 0 ;;
*) echo "Please select choice 1,2,3 or q";
echo "Press any key to continue" ; read ;;
esac
done

 
Since this is a separate question you should really start a new thread.

However, since I'm here already... there is nothing preventing you from putting another case statement inside the existing one, so you can repeat the similar code under one of the menu options.

Annihilannic.
 
I have got an input file called atp having 2 columns like below:

createcase createaa
createcase createbb
createcase createcc
......

I would like to search in the system if there are running processes based on 2nd column such as $2.

So far this is what i wrote:
########################################################


echo Check - ATP

echo > OK
echo > WARNING

ps -aef | grep $ENVIRONMENT | grep ATP | awk '{print $2}' atp | wc -l | read x
if [ $x == 0 ]
then
awk '{ printf " ERROR : ATP %s is not running!", $2 }' atp >> ERRORS
else
awk '{ printf " MESSAGE : ATP %s is running!", $2 }' atp >> OK
fi

cat OK
cat ERRORS

rm OK
rm ERRORS

########################################################

The $x value if it is like that it returns the total number of processes but i want it to check each and every processes not the total.

Please i would realy appreciate your help
 
There are a couple of problems with that code; the logic isn't quite correct, and awk won't process the piped input when you also specify an input file "atp". You can get around that by specifying a second input file "-" which means to read stdin.

You need to do a for loop and check for each process individually, or else you can do it all in awk, something like this perhaps:

Code:
> OK > ERRORS
ps -eo args | awk -v ENV=$ENVIRONMENT '
    # Read in atp file
    NR==FNR { atp[$2]; next }
    # Check for running processes
    $0 ~ ENV && /ATP/ && ($3 in atp) { running[$3] }
    # Create output files
    END {
        for (p in atp) {
            if (p in running) {
                print "MESSAGE: ATP " p " is running!" >> "OK"
            } else {
                print "ERROR: ATP " p " is not running!" >> "ERRORS"
            }
        }
    }
' atp -

cat OK
cat ERRORS

Annihilannic.
 
Hi Annihilannic,

I have tried to go through your code very well and copied and paste as it is, it only returned the ERROR messages and due to this $0 ~ ENV && /ATP/ && ($3 in atp) { running[$3] }

Based on my understanding, $3 is the last column from the system which it is process name that should be checked.Correct me if im wrong.

Ok based on my system,the last column is on column 12 and i have used $12 instead of $3, it works fine.

One last question for you, they want me to include a 3rd column called which has got values such:

createcase createaa 1
createcase createbb 2
createcase createcc 4
......

The aim of the 3rd column will be used to compare if the number of running processes on the system is equal to the one in 3rd column,basically we must have 3rd output file called WARNINGS.

The code should look like as follows:
There are a couple of problems with that code; the logic isn't quite correct, and awk won't process the piped input when you also specify an input file "atp". You can get around that by specifying a second input file "-" which means to read stdin.

You need to do a for loop and check for each process individually, or else you can do it all in awk, something like this perhaps:


The code should look like this even though there is no logic at least u will understand what im trying to say:

echo > ERRORS
echo > OK
echo > WARNINGS

ps -aef | grep $ENVIRONMENT | grep ATP | awk '{print $2}' atp | wc -l | read x
if [ $x == 0 ]
then
awk '{ printf " ERROR : ATP %s is not running!", $2 }' atp >> ERRORS
elif [ $x != $3 ]
then
awk '{ printf " WARNING : ATP %s - only $x of 5 instances running!", $2 }' atp >> WARNINGS
else
awk '{ printf " MESSAGE : ATP %s is running!", $2 }' atp >> OK
fi


The OK and ERRORS is working fine, Im battling to encoperate it on your working code, I mean the WARNING part.

The output file for WARNINGS should be:
WARNING : ATP createbb - only 1 of 2 instances running!

this is based on createbb if 1 out of 2 is running!

I would be really happy for this.


 
Hi Annihilannic,

I have tried to go through your code very well and copied and paste as it is, it only returned the ERROR messages and due to this $0 ~ ENV && /ATP/ && ($3 in atp) { running[$3] }

Based on my understanding, $3 is the last column from the system which it is process name that should be checked.Correct me if im wrong.

Ok based on my system,the last column is on column 12 and i have used $12 instead of $3, it works fine.

One last question for you, they want me to include a 3rd column called which has got values such:

createcase createaa 1
createcase createbb 2
createcase createcc 4
......

The aim of the 3rd column will be used to compare if the number of running processes on the system is equal to the one in 3rd column,basically we must have 3rd output file called WARNINGS.

The code should look like this even though there is no logic at least u will understand what im trying to say:

echo > ERRORS
echo > OK
echo > WARNINGS

ps -aef | grep $ENVIRONMENT | grep ATP | awk '{print $2}' atp | wc -l | read x
if [ $x == 0 ]
then
awk '{ printf " ERROR : ATP %s is not running!", $2 }' atp >> ERRORS
elif [ $x != $3 ]
then
awk '{ printf " WARNING : ATP %s - only $x of 5 instances running!", $2 }' atp >> WARNINGS
else
awk '{ printf " MESSAGE : ATP %s is running!", $2 }' atp >> OK
fi


The OK and ERRORS is working fine, Im battling to encoperate it on your working code, I mean the WARNING part.

The output file for WARNINGS should be:
WARNING : ATP createbb - only 1 of 2 instances running!

this is based on createbb if 1 out of 2 is running!

I would be really happy for this.



 
Another thing, you mentioned this "You need to do a for loop and check for each process individually, or else you can do it all in awk, something like this perhaps"

Individually do u mean something like :
ps -aef | grep $ENVIRONMENT | grep ATP | grep createaaa | wc -l | read x
if [ $x == 0 ]
then
echo ERROR: ATP createlaaa is not running! >> ERRORS
else
echo MESSAGE: ATP createaaa ALL OK! >> OK
fi

......
......

I mean if so, what if the inputfile is so big I mean repeating a code will consume time.
 
Notice that I used ps -eo args, that is why the column numbering is different.

I mean something like this:

Code:
#!/bin/ksh

> ERRORS > OK > WARNINGS

while read CREATECASE CREATEXX N
do
        COUNT=$(ps -eo args | grep -v grep | grep -c $CREATEXX)
        if [[ "$COUNT" -eq 0 ]]
        then
                echo "ERROR: ATP $CREATEXX is not running!" >> ERRORS
        elif [[ "$COUNT" -ne "$N" ]]
        then
                echo "WARNING: ATP $CREATEXX - only $COUNT of $N instances running!" >> WARNINGS
        else
                echo "MESSAGE: ATP $CREATEXX is running!" >> WARNINGS
        fi
done < atp

cat ERRORS WARNINGS OK

How big is the input file going to be? The above code should run pretty quickly for a fairly large number of processes; but if you wish to improve the speed you could save the ps output in a file perhaps and read that instead of running ps each time.

Annihilannic.
 
I mean this code of yours works fine on my machine and does what is supposed to do:

echo "Check - ATP\n"
> OK > ERRORS
ps -eaf | awk -v ENV=$ENVIRONMENT '
# Read in atp file
NR==FNR { ref[$2]; next }
# Check for running processes
$0 ~ ENV && /ATP/ && ($12 in ref) { running[$12] }
# Create output files
END {
for (p in ref) {
if (p in running) {
print "MESSAGE: ATP " p " is running!" >> "OK"
} else {
print "ERROR: ATP " p " is not running!" >> "ERRORS"
}
}
}
' atp -
cat OK ERRORS
echo "\nFinished Checking"


N.B what is now left is to have some WARNINGS but those warnings are based the 3rd column like

if [ $x == 0 ]
then
awk '{ printf " ERROR : ATP %s is not running!", $2 }' atp >> ERRORS
elif [ $x != $3 ]
then
awk '{ printf " WARNING : ATP %s - only $x of 5 instances running!", $2 }' atp >> WARNINGS
else
awk '{ printf " MESSAGE : ATP %s is running!", $2 }' atp >> OK
fi

This code should be in awk script up there!!!
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top