1

I was just curious, what may be the reason why script run two instances when executed.

Whenever I run my script foo.sh, and when I check using:

$ ps -ef | grep foo.sh

It always returns two instances.

user 30643 28793  0 11:09 pts/4    00:00:00 /bin/sh /foo.sh
user 30645 30643  0 11:09 pts/4    00:00:04 /bin/sh /foo.sh

foo.sh

Here's the contents of the script.

#!/bin/sh 

string="<IPADDRESS>" 
string2="<HOSTNAME>" 
string3="|" 
_date=$(date +"%D") 
_time=$(date +"%T") 


tail -n 0 -F /tmp/snmp_debug.log | \ 
while read LINE 
do 
echo $LINE | grep -q $string 
if [ $? = 0 ] 
then 
hostAdd=$(echo $LINE | awk -F'[][]' '{print $2;}') 
echo "HostIP: $hostAdd" >> sqlInsert.log 
fi 

echo $LINE | grep -q $string2 
if [ $? = 0 ] 
then 
echo "$_date $_time" >> sqlInsert.log 
hostName=$(echo $LINE | awk -F'[<>]' '{print $4}') 
echo "Hostname: $hostName" >> sqlInsert.log 
fi 

echo $LINE | grep -q $string3 
if [ $? = 0 ] 
then 
#output number of delimiters 
pipeNo=$(echo $LINE | awk -F '|' '{print NF-1}') 

#CCN Alarms 
if [ $pipeNo == 8 ] 
then 
echo $pipeNo >> sqlInsert.log 
errorTrim=$(echo $LINE | awk -F '[|-]' '{print $7}') 
echo $errorTrim >> sqlInsert.log 

#map CCN severity 
sevLev=$(echo $LINE | awk -F '|' '{print $7}') 
if [ $sevLev == 1 ] 
then 
sevLev=1; 
elif [ "$sevLev" -ge 2 ] && [ "$sevLev" -lt 6 ] 
then 
sevLev=10; 
elif [ $sevLev == 6 ] 
then 
sevLev=5; 
fi 
echo "Sev $sevLev" >> sqlInsert.log 

probCause_t=$(echo $LINE | awk -F '|' '{print $6}') 
probCause=$(grep -E "^$probCause_t" CCNProbCause.lookup | awk -F '|' '{ print $2 }') 
echo "ProbCause $probCause" >> sqlInsert.log 
alarmRem1=$(echo $LINE | awk -F '|' '{print $3 $8 $9}') 
alarmRem2=$(echo $alarmRem1 | sed "s/\"//g;s/\://g") 
alarmRem="$probCause $alarmRem2" 
echo "Rem $alarmRem" >> sqlInsert.log 
C_type=$(echo $LINE | awk -F '|' '{print $5}') 
echo "C-type $C_type" >> sqlInsert.log 
alarmType=$(grep -E "^$C_type" EricssonEventsCCN.lookup | awk -F '|' '{ print $2 }') 
echo "Type $alarmType" >> sqlInsert.log 


##Connect and insert to DB >> CCN 
sqlplus -s UPM_USER/UPM_USER << EOF >> sqlInsert.log 
insert into alarmlog_06 (errorid,agentid,moduleid,moduleinstance,hostaddress,severity,remarks,status,entrydate,umuidate,classid) VALUES ($errorTrim,28,6034,1,'$hostAdd',$sevLev,'$alarmRem','P',sysdate,sysdate,$alarmType); 
commit; 
exit; 
EOF 

#echo "Done Inserting to DB" >> sqlInsert.log 
echo "======================================" >> sqlInsert.log 

#SDP & AIR Alarms 
elif [ $pipeNo == 5 ] 
then 
echo "Pipe: $pipeNo" >> sqlInsert.log 
probCause_t=$(echo $LINE | awk -F '|' '{print $5}') 
probCause=$(grep -E "^$probCause_t" SDPAIRProbCause.lookup | awk -F '|' '{ print $2 }') 
echo "ProbCause $probCause" >> sqlInsert.log 
alarmRem1=$(echo $LINE | awk -F '|' '{print $3}') 
alarmRem2=$(echo $alarmRem1 | sed "s/\"//g;s/\://g;s/\;//g") 
#alarmRem="$alarmRem2 $probCause" 
alarmRem="$alarmRem2" 
echo "Rem $alarmRem" >> sqlInsert.log 
SA_type=$(echo $LINE | awk -F '|' '{print $4}') 
alarmEType=$(grep -E "^$SA_type" EricssonEventsSDP.lookup | awk -F '|' '{ print $2 }') 
echo "EventType $alarmEType" >> sqlInsert.log 
alarmModesc=$(echo $LINE | awk -F '[|-]' '{print $7}') 
echo "AlarmModelDesc $alarmModesc" >> sqlInsert.log 
moduleid=$(grep "$alarmModesc" EricssonLookup.lookup | awk -F '|' '{ print $4 }') 
echo "MOduleID $moduleid" >> sqlInsert.log 

#map Severity for SDP & AIR 
sev1=$(echo $LINE | awk -F '|' '{print $6}') 
echo "Severity $alarmSev" >> sqlInsert.log 
if [ -z "$sev1" ] 
then 
sev=$(grep "$alarmModesc" EricssonLookup.lookup | awk -F '|' '{ print $3 }') 
if [ -z "$sev" ] 
then 
sev=10; #default severity for sdp&air (10) error 
else 
#map returned severity value 
if [ $sev == 1 ] 
then 
sev=1; 
elif [ "$sev" -ge 2 ] && [ "$sev" -lt 6 ] 
then 
sev=10; 
elif [ $sev == 6 ] 
then 
sev=5; 
fi 
fi 
echo "Severity $sev" >> sqlInsert.log 
else 
sev=$sev1 
fi 

errornum=$(grep "$alarmModesc" EricssonLookup.lookup | awk -F '|' '{ print $2 }') 
if [ -z "$errornum" ] 
then 
errornum= 
insertstring="insert into alarmlog_06 (agentid,moduleinstance,hostaddress,severity,remarks,status,entrydate,umuidate,classid) VALUES (28,1,'$hostAdd',$sev,'$alarmRem','P',sysdate,sysdate,$alarmEType);" 
echo "ErrorID Not Found" >> sqlInsert.log 
else 
insertstring="insert into alarmlog_06 (errorid,agentid,moduleid,moduleinstance,hostaddress,severity,remarks,status,entrydate,umuidate,classid) VALUES ($errornum,28,$moduleid,1,'$hostAdd',$sev,'$alarmRem','P',sysdate,sysdate,$alarmEType);" 
echo "ErrorID $errornum" >> sqlInsert.log 
fi 

##Connect and insert to DB 
sqlplus -s UPM_USER/UPM_USER << EOF >> sqlInsert.log 
$insertstring 
commit; 
exit; 
EOF 
echo "========================================" >> sqlInsert.log 
fi 
fi 
done
  • Just hazarding a guess here, but do any of the script's commands end with a '&'? – mikeserv Mar 4 '14 at 4:07
  • No. None of the commands in the script has '&' – user60216 Mar 4 '14 at 5:24
  • 1
    I left a comment to you in chat, can you please provide the contents of this foo.sh, otherwise we cannot assist you further, and I'll be forced to vote your Q closed as unclear. – slm Mar 4 '14 at 6:38
1

As slm, finally reached in his last comment, it depends on what foo.sh is actually doing. And you've not provided any part of this shell script.

For example, the following simple script will net the same result:

#!/bin/bash

( true; sleep 10 ) &
wait

Gives:

# /tmp/foo.sh &
[1] 14663
# pgrep foo.sh
14663
14670

(note: bash is smart enough to not run a sub-shell for a single, simple command, thus the true.)

UPDATE

Looking at the script you've now post, this is the expected behavior. Your script requires two processes. One is the main stream of commands (i.e. the one running tail), and the second is the sub-shell running the while loop.

0

The string you're grepping for is being returned as a match as well.

Example

Say I run this fake process called sleep 100.

$ sleep 100 &

I now check ps looking for processes named sleep.

$ ps -ef | grep sleep
sam      31473 31256  0 22:22 pts/6    00:00:00 sleep 100
sam      31476 31256  0 22:22 pts/6    00:00:00 grep sleep

The old school way of getting rid of this, is to make use of a trick and tell grep to search for a string using a regular expression (regex).

$ ps -ef | grep "[s]leep"
sam      31485 31256  0 22:24 pts/6    00:00:00 sleep 100

This makes use of the fact that grep is literally looking for whatever you tell it to find, in this case "[s]leep" but that doesn't match. The string [s]leep as a regular expression is equivalent to the string "sleep". The notation [..] is a set, in this case it contains 1 item, the letter s.

Modern method

A more modern method is to make use of the command pgrep. This command is designed to return information about processes by their name, however it's designed to omit matches that include pgrep.

$ pgrep sleep
31494

-or-

$ pgrep -l sleep
31494 sleep

But it's not a duplicate from grep

In your updated question you listed the output of ps like so:

user 30643 28793  0 11:09 pts/4    00:00:00 /bin/sh /foo.sh
user 30645 30643  0 11:09 pts/4    00:00:04 /bin/sh /foo.sh

This would seem to indicate that you have in fact 2 separate processes. I would kill the both of them and then restart it. You can use this command to kill both of them:

$ pkill -f /foo.sh
  • i used pgrep, but it still outputs two instances. I believe the two instances are both valid. How can i prevent two instances from running? – user60216 Mar 4 '14 at 3:33
  • @user60216 - how are you starting them/it? BTW, I wrote the upper portion of my A prior to you updating the Q. – slm Mar 4 '14 at 3:34
  • using this: ./foo.sh & and then again, two instances will run.. – user60216 Mar 4 '14 at 3:40
  • when I kill both of them, and then restart using the command i said above, it will return two instances again. – user60216 Mar 4 '14 at 3:41
  • @user60216 - I'm confused, you're running the script 2 times, so what's actually wrong? ./foo.sh & runs the script backgrounded, running this 2 times runs it twice. – slm Mar 4 '14 at 3:43
0

That's the expected behaviour.

Here if you will look at PPID (Parent Process IDs), second shell's PPID which is 30643 is same as first shell's PID. So it means first shell has called another shell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.