Inconsistent `ps -eaf -o args | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc -l`

i have this line of code that looks for the same file if it is currently running and returns the count.

`ps -eaf -o args | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc -l`

basically it is assigned to a variable

ISRUNNING=`ps -eaf -o args | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc -l`

the problem is that most of the time it returns inconsistent number when there are no other same process in this case the sfs_pcard_load_file.ksh is currently running. it returns 2 or 3 when it should be only returning 1 right?

i tried this code also and giving me the same issue.

ISRUNNING=`ps -ef | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc -l`

i am using the code in this korn shell script below.

#!/usr/bin/ksh
#####################################################################
#
# Initialization file
#--------------------------------------------------------------------
. ./pcard_load_data.ini


#####################################################################
#
# Parameter definition
#--------------------------------------------------------------------
pSec=$1
pLoopCnt=$2

#
#####################################################################
#
# Variable Initialization
#--------------------------------------------------------------------
#
CURDATE=`date +%m/%d/%Y" "%H:%M:%S`
#LOGDATE=`date +%m%d%Y"_"%H%M%S`
LOGDATE=`date +%m%d%Y"`
JOBNAME=`basename $0 | cut -d. -f1`
LOG_FILE=${LOG_DIR}/${JOBNAME}_${LOGDATE}.log
LOG_FILE_ERROR=${LOG_DIR}/${JOBNAME}_${LOGDATE}_err.log
ORALOGFILE=${LOG_DIR}/PCARDDAILY${LOGDATE}.log

# log file header
echo "+------------------------------------------------------------+" >> $LOG_FILE
echo "This is the log file of pcard_load_file.ksh script"  >> $LOG_FILE
echo "Run date: $CURDATE\n" >> $LOG_FILE

#####################################################################
#
# Check for required number of parameters if any are expected
#--------------------------------------------------------------------
#
if [[ $# == 0 ]]; then
  print "WARNING: Required Parameters Missing."
  print "USAGE: `basename $0`"
  echo "WARNING: Required Seconds and Number of Attempts Parameters Missing"  >> $LOG_FILE
  echo "example usage: `basename $0` 30 10\n">> $LOG_FILE
  # use the default number when parameter is missing
  pSec=60
  pLoopCnt=10
  #exit 1
fi
#


#
#####################################################################
#
# Step: 1
#
# Check for already running process and any files to process
#
#--------------------------------------------------------------------
#
echo "Step 1 Start..." >> $LOG_FILE
ctr=0
while [ ${ctr} -lt ${pLoopCnt} ] 
do
  ISRUNNING=`ps -eaf -o args | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc -l`
  ctr=$(($ctr + 1))
  echo "number of same process currently running: $ISRUNNING" >> $LOG_FILE
  echo "number of attempt to check for duplicate runs: $ctr" >> $LOG_FILE
  if (( ${ISRUNNING} > 1 )); then
    echo "ERROR: Process is already running." >> $LOG_FILE
    if (( ${ctr} == ${pLoopCnt} )); then
      echo "Please contact apps dev group" >> $LOG_FILE
    fi
    echo "+-----+\n" >> $LOG_FILE
    if ((${ctr} == ${pLoopCnt})) then
      exit 0
    fi
  else
    ctr=10
  fi
  sleep $pSec
done
#
NUMFILES=`ls -1 $INPUT_DIR | wc -l`
 if (( ${NUMFILES} == 0 )); then
   echo "WARNING: There are no files in input directory to process.\n" >> $LOG_FILE
   exit 1
 fi
echo "End of Step 1\n" >> $LOG_FILE
#
#####################################################################
#
# Step: 2
#
# Process files in INPUT_DIR
#
#--------------------------------------------------------------------
#
echo "Step 2 Start...\n" >> $LOG_FILE
cd $INPUT_DIR
#
NUMFILES=`ls -1 *.csv | wc -l`
 if (( ${NUMFILES} == 0 )); then
   echo "WARNING: There are no files in process directory.\n" >> $LOG_FILE
   #if there are no input files there will be no output file to be created
   #needs to create a null output file
   cp pcard.null PCARDDAILY${LOGDATE}.txt
   echo "         Created the $INPUT_DIR/PCARDDAILY${LOGDATE}.txt null file to replicate the required file.\n" >> $LOG_FILE
   #needs to create a database log file PCARDDAILY${LOGDATE}.log
   echo "WARNING: There are no extracted files.\n" >> $ORALOGFILE
   exit 0
 fi
#
 for filename in $(ls -1 *.csv)
 do
  echo "Processing $filename \n" >> $LOG_FILE
  #
  echo "Copied $filename to log directory: $LOG_DIR\n" >> $LOG_FILE
  cp $filename $LOG_DIR
  #
  echo "Executed PL/SQL package for $filename\n" >> $LOG_FILE
  SQL_LOG_FILE=${LOG_DIR}/${filename}_${LOGDATE}.log
  DB_RSLT=`sqlplus -s <<EOF >> $SQL_LOG_FILE
   $USERID
   declare
    v_result varchar2(200);
   begin
    cca_app.Pa_SFS_PCARD_Daily_Bulkload.Pr_Daily_Process('$filename');
   end;
/ 
   exit 0
  EOF`
  wait
  #
  RC=$?
  #
  echo $DB_RSLT >> $LOG_FILE
  echo "Deleted $filename from $INPUT_DIR\n" >> $LOG_FILE
  rm -f $filename
  #
 done
 echo "End of Step 2\n" >> $LOG_FILE

#
#####################################################################
#
# Step: 3
#
# check for file PCard (Output PCARDDAILY*.txt) 
#
#--------------------------------------------------------------------
#
echo "Step 3 Start...\n" >> $LOG_FILE
cd $INPUT_DIR
#
NUMFILES=`ls -1 PCARD*.txt | wc -l`
 if (( ${NUMFILES} == 0 )); then
   echo "WARNING: There are no PCARD*.txt files in the output $INPUT_DIR directory.\n" >> $LOG_FILE
   cp pcard.null PCARD${LOGDATE}.txt
   echo "         Created a PCARD${LOGDATE}.txt null file to replicate the file.\n" >> $LOG_FILE
   exit 1
 fi
#
echo "End of Step 3\n" >> $LOG_FILE

#
#####################################################################
#
# Step: 4
#
# delete files from log and completed dir > 30 days old   
#
#--------------------------------------------------------------------
#
echo "Step 4 Start...\n" >> $LOG_FILE
#
cd $LOG_DIR
find . -name "*.csv" -mtime +30 -exec rm -f {} \;                 
cd ${LOG_DIR}                                                                  
find . -name "*.log" -mtime +30 -exec rm -f {} \;                 
#
 echo "End of Step 4\n" >> $LOG_FILE
#
exit 0

please advise thank you.

-warren

You might also fuser the shell script to see what PIDs have it open.

i tried this and it does not return anything

$ fuser -V sfs_pcard_load_file.ksh
sfs_pcard_load_file.ksh:

$

in the script

fopen=`fuser -V sfs_pcard_load_file.ksh`
echo "file open info: $fopen" >> $LOG_FILE

What's your OS?

The traditional way to avoid ps | grep | cut | sed | awk | tr | ed | head | tail | kitchen | sink is to use a PID file. Store your program's PID ($$ in shell) in a file so other things can track if you're still running or died unexpectedly.

#!/bin/sh

# Traditional location is /var/run/..., but not everything can write there
PIDFILE="/tmp/sfs_pcard.pid"

if [ -e "$PIDFILE" ]
then
        read PID < "$PIDFILE"
        if ps "$PID" >/dev/null 2>/dev/null
        then
                echo "$PIDFILE has $PID, which is still running" >&2
                exit 1
        fi
fi

# PID file either missing, or the process in it no longer exists.
echo "$$" > "$PIDFILE"
# Delete the PID file when the process exits
trap "rm -f '$PIDFILE'" EXIT

# Rest of the program's code.
...

Much less of a kludge and should work on most systems.

OS is IBM-AIX Version 6.1

---------- Post updated at 04:40 PM ---------- Previous update was at 03:48 PM ----------

i run this script with these small line of codes for debugging purpose.

sfs_pcard_load_file.ksh

#!/usr/bin/ksh
ISRUNNING=`ps -eaf -o args | grep -i sfs_pcard_load_file.ksh | grep -v grep | wc
 -l`
pInfo=`ps -eaf -o args | grep -i sfs_pcard_load_file.ksh`
echo "number of same process currently running: $ISRUNNING"
echo "these are the process currently running: $pInfo"

and it returned this output:

$ sh sfs_pcard_load_file.ksh
number of same process currently running:        2
these are the process currently running: grep -i sfs_pcard_load_file.ksh
sh sfs_pcard_load_file.ksh

it looks like the grep command inside the script is also being counted. how do i exclude it? please advise. thank you.

As Corona688 pointed out, try and use a PID file - It's more portable reliable and best practice.

As for your ps issue, avoid using -f and -o args these two arguments are at odds with each other -f is for full listing and -o is limiting to specific list of arguments.

One popular way to avoid counting the grep command is to use an RE that doesn't match itself for example:

ISRUNNING=`ps -e -o args | grep -i fs_pcard_load_file.ksh | wc -l`