Home > OS >  Adjust elapsed time for 5 hours?
Adjust elapsed time for 5 hours?

Time:11-06

I have the following script that basically looks for a certain process name and tracks if its elapsed for more than X time, to kill it.

#!/bin/bash

PROC_NAME=my_proc_name

# Get all PIDs for process name
procs=(`ps aux | grep  $PROC_NAME | awk '{print $2}'`)

# for each PID in PIDs array
for pid in $procs; do
    # get elapsed time in form mm:ss and remove ":" character
    # to make it easier to parse time 
    time=(`ps -o etime $pid | sed -e 's/[:-]/ /g'`)
    # get minutes from time
    min=${time[1]}
    # if proces runs 5 hours then kill it
    if [ "$min" -gt "300" ]; then
        kill -9 $pid
    fi
done;

This version of the script kills the process if the elapsed time exceeds 5 mins. But what if i want to account for an elapsed time of 5 hours instead?

I thought itd be as simple as adjusting 5 mins to 300 mins (60 mins x 5 = 300mins = 5 hours) but i realized that the format is hours:min:secs .. so will need to make sure sed gets the hours, right? if so, how do i do that?

CodePudding user response:

You can use bash regular expression to get different components :

#!/bin/bash

PROC_NAME=my_proc_name

# Get all PIDs for process name
procs=(`ps aux | grep  $PROC_NAME | awk '{print $2}'`)

pattern='((.*)-)?((..):)?(..):(..)'

for pid in ${procs[@]}; do
    if [[ "$(ps -o etime= -p $pid)" =~ $pattern ]] && {
       [ -n "${BASH_REMATCH[2]}" ] || # if day component exists, then it's more than 5 hours
       { [ -n "${BASH_REMATCH[4]}" ] && ((10#${BASH_REMATCH[4]} >= 5)); } }; then
        echo kill -9 $pid
    fi
done

Remove echo (dry run) if you see the result is expected.

Explanation of pattern='((.*)-)?((..):)?(..):(..)' :

1) ((.*)-)? means optional day component
   if present like 9- then ${BASH_REMATCH[1]} = 9-, ${BASH_REMATCH[2]} = 9
   if absent, ${BASH_REMATCH[2]} is empty
2) ((..):)? means optional hour component
   if present like 05 then ${BASH_REMATCH[3]} = 05:,${BASH_REMATCH[4]} = 05
   if absent, ${BASH_REMATCH[4]} is empty

CodePudding user response:

Usually, on many systems, I transform the ps elapsed time in seconds with awk:

#! /bin/bash

...

declare -i E_TIME=$(ps \
    -p ${THE_PID} \
    -o etime=     \
| awk '
    {
        gsub(/^  /, "")
        gsub(/  $/, "")
    }
    /^[0-9]*-/ {
        days = $0
        gsub(/-.*$/, "", days)
        gsub(/^0 /,  "", days)
        if (days == "") days = "0"
        gsub(/^[0-9] -/, "", $0)
    }
    /^[0-9] :[0-9] :[0-9] $/ {
        hours = $0
        gsub(/:.*$/, "", hours)
        gsub(/^0 /,  "", hours)
        if (hours == "") hours = "0"
        gsub(/^[0-9] :/, "", $0)
    }
    /^[0-9] :[0-9] $/ {
        minutes = $0
        gsub(/:.*$/, "", minutes)
        gsub(/^0 /,  "", minutes)
        if (minutes == "") minutes = "0"
        gsub(/^[0-9] :/, "", $0)
    }
    /^[0-9] $/ {
        seconds = $0
        gsub(/:.*$/, "", seconds)
        gsub(/^0 /,  "", seconds)
        if (seconds == "") seconds = "0"
    }
    {
        print seconds   60 * (minutes   60 * (hours   24 * days) )
    }
'
)

echo "E_TIME=${E_TIME}"
  •  Tags:  
  • bash
  • Related