O script sempre executa duas instâncias

1

Eu estava apenas curioso, qual pode ser a razão pela qual o script executa duas instâncias quando executado.

Sempre que eu executar meu script foo.sh e quando eu verificar usando:

$ ps -ef | grep foo.sh

Ele sempre retorna duas instâncias.

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

Este é o conteúdo do 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
    
por user60216 04.03.2014 / 04:15

3 respostas

1

Como slm, finalmente alcançado em seu último comentário, isso depende de qual foo.sh está realmente fazendo. E você não forneceu nenhuma parte deste script de shell.

Por exemplo, o script simples a seguir terá o mesmo resultado:

#!/bin/bash

( true; sleep 10 ) &
wait

Dá:

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

(nota: bash é inteligente o suficiente para não executar um sub-shell para um único comando simples, assim o true .)

UPDATE

Olhando para o script que você agora postou, esse é o comportamento esperado. Seu script requer dois processos. Um é o fluxo principal de comandos (ou seja, aquele que está executando tail ), e o segundo é o sub-shell executando o loop while .

    
por 04.03.2014 / 08:13
0

A string que você está procurando está sendo retornada como uma correspondência também.

Exemplo

Digamos que eu execute este processo falso chamado sleep 100 .

$ sleep 100 &

Verifico agora ps procurando por processos denominados 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

A maneira antiga de se livrar disso, é fazer uso de um truque e dizer a grep para procurar por uma string usando uma expressão regular (regex).

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

Isso faz uso do fato de que grep está literalmente procurando o que você disser para encontrar, neste caso "[s] leep" mas que não corresponde. A string [s]leep como expressão regular é equivalente à string "sleep". A notação [..] é um conjunto, neste caso contém 1 item, a letra s .

Método moderno

Um método mais moderno é fazer uso do comando pgrep . Este comando é projetado para retornar informações sobre os processos por seus nomes, no entanto, ele foi projetado para omitir correspondências que incluam pgrep .

$ pgrep sleep
31494

-or-

$ pgrep -l sleep
31494 sleep

Mas não é uma duplicata do grep

Na sua pergunta atualizada, você listou a saída de ps da seguinte forma:

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

Isso parece indicar que você tem, de fato, dois processos separados. Eu mataria os dois e depois o reiniciaria. Você pode usar este comando para matar os dois:

$ pkill -f /foo.sh
    
por 04.03.2014 / 04:25
0

Esse é o comportamento esperado.

Aqui, se você der uma olhada no PPID (Parent Process IDs), o PPID do segundo shell, que é 30643, é o mesmo do PID do primeiro shell. Então isso significa que o primeiro shell chamou outro shell.

    
por 17.11.2017 / 11:13