Extract character from string

ps -eaf | grep �oracleTRLV (LOCAL=NO)� | while read ora_proc
do
echo $ora_proc
done

I would like to modify the above shell so that if character 13 and 14 equal "12" to do something.

Sorry I'm new to shell:(

grep -v '^.\{11\}12'

ps -eaf | grep �oracleTRLV (LOCAL=NO)� |  grep -v '^.\{12\}12' | \
while read ora_proc 
do
echo $ora_proc
done

This skips over any output from ps the has a "12" starting at pos 13

I have to build the "12" dinamically (number of minutes) and to check if what's in the string at that position is greater then this ("12" in this case) number of minutes.

ps -eaf |
 awk '/oracleTRLV (LOCAL=NO)/ && substr($0,13,2) >= 12 {
    print substr($0,13,2), $0}
' |
 while read num ora_proc
 do
     echo num=$num
     echo $ora_proc
 done

Chris, I don't see in the script how do you build the number of minutes.

Let me explain what I want to do: I have an application that creates processes in HP-Unix that for some reason don't "die".
The result of:
ps -eaf|grep "oracleTRLV (LOCAL=NO)"

are rows like this:
oracle 1769 1 0 15:24:13 ? 0:00 oracleTRLV (LOCAL=NO)

I want to make a shell (I will run it every 15 minutes) that will take each row and "kill" all the processes that are older then 15 minutes.

By the way, I bought your book "Shell Scripting Recipes" but is way to advanced for me.

So, how do I start?

If you're on Solaris, look into:

ps -e -o pid,etime,comm

'man ps' yields:

     etime In the POSIX locale, the elapsed time since  the  pro-
           cess was started, in the form:

           [[dd-]hh:]mm:ss

           where

     dd    is the number of days

     hh    is the number of hours

     mm     is the number of minutes

     ss    is the number of seconds

     The dd field will be a decimal integer. The hh,  mm  and  ss
     fields will be two-digit decimal integers padded on the left
     with zeros.

The it becomes a matter of simple parsing of the second field and converting it to seconds and comparing it against your crontab scheduling policy (15mins).

I'm on HP-Unix 10 and the above doesn't work.

Stupid questions:
1) How do I assign a value to a variable in hp-unix?
2) How do I concatenate 2 variables in hp-unix?
3) How do I write an "if" statement in hp-unix?
4) How to I extract a piece of a string inside an "if" statement?

Try the below code:

Caveat: Ensure to test this before implementing as I have NOT tested it. Before running the kill command, maybe replace with a echo command just to be on the safer side.

 
export UNIX95=<WHITESPACE>
ps -eo pid,etime,comm | grep "oracleTRLV (LOCAL=NO)" | while read line
do
  time_taken=$(echo ${line} | awk '{print $2}')
  if [[ $(echo ${time_taken} | grep "-" | wc -l) -gt 0 ]]; then
    time_taken_days=$(echo ${time_taken} | cut -d "-" -f1)
  else
    time_taken_days=0
  fi
  time_taken_hrs=$(echo ${time_taken} | cut -d "-" -f2 | cut -d ":" -f1)
  time_taken_min=$(echo ${time_taken} | cut -d "-" -f2 | cut -d ":" -f2)
  total_time_taken=$(( (${time_taken_days} * 24 * 60) + (${time_taken_hrs} * 60) + ${time_taken_min} ))
  if [[ ${total_time_taken} -gt 15 ]]; then
    pid_to_be_killed=$(echo ${line} | awk '{print $1}')
    kill -9 ${pid_to_be_killed}
  fi
done
 

HTH,:cool:

Regards,

Praveen

Praven,
there is an error message:
ps: illegal option -- o
usage: ps [-edaflPx] [-u ulist] [-g glist] [-p plist] [-t tlist] [-R prmgroup]

:frowning:

Which "above" are you talking about? More than one script has been posted.

What does "doesn't work" mean exactly? What does happen?

Please post exactly what you tried and exactly what output there was and copy any error messages exactly.

These questions have nothing to do with HP-UX itself, but with the shell you are using. Make sure that you are using a POSIX shell. That may or may not be /bin/sh.

They are all very basic shell scripting questions, so basic, in fact, that I wonder if they are really what you want to ask.

I don't "build", I extract. I used awk's substr() function, but it have been "cut -c13,14". Better still is the method below.

Please use

 tags rather than changing font or size.



ps -eaf|grep "oracleTRLV (LOCAL=NO)"

are rows like this:

oracle 1769 1 0 15:24:13 ? 0:00 oracleTRLV (LOCAL=NO)

[/quote]

[indent]
Whoa! Which characters do you want? I don't think it's 13 and 14. And can you be sure that what you want is always in the same columns?

It would be better to read fields rather than characters. Which field (or part of a field) do you want?

a: oracle
b: 1769
c: 1
d: 0
e: 15:24:13
f: ?
g: 0:00
h: oracleTRLV (LOCAL=NO)

Presumably you want part of either e or g. I'd guess it's g.

You can read each field into a separate variable:

ps -eaf |
 while read user pid c d e f g command
 do
    ## get the minutes from $g
    temp=${g%:*}
    mins=${temp##*:}
    if [ ${mins#0} -gt 12 ]
    then
      kill $pid  ## you may need to add a signal
    fi
 done

temp=${g%:}
mins=${g##
:}

It's not a tutorial, but there are many simple scripts you should be able to understand.

Thank you.

Note the edit I just made to the script.

  mins=${temp##*:}  ## was: mins=${g##*:}

Nicoman,

ps -o does NOT work in HP-UX unless the env variable UNIX95 is set to null or whitespace. That is the reason why the first line of my code was:

export UNIX95=<enter whitespace here>

Moreover, the script (which initially was erroring out with ps --o is an invalid option) is working fine for me, when I added the export UNIX95=<whitespace> at the beginning of the script.

Anyway, Chris has given u a much simpler option!! As usual, Chris rocks!!:slight_smile:

Regards, :cool:

Praveen

They say that "if you want to do something do it by yourself" :slight_smile: ... so I went to the book stoor in the weekend and I bought a book. I did some reading in the weekend and I made the program this morning in 10 minutes (see below). Piece of cake compared to .net :smiley:

ps -eaf | grep �oracleTRLV (LOCAL=NO)� | while read line
do
nick_owner=$(echo ${line} | awk '{print $1}')
nick_pid=$(echo ${line} | awk '{print $2}')
nick_priority=$(echo ${line} | awk '{print $4}')
nick_time=$(echo ${line} | awk '{print $5}')
nick_time_taken_hrs=$(echo ${nick_time} | cut -d ":" -f1)
nick_time_taken_minutes=$(echo ${nick_time} | cut -d "-" -f2 | cut -d ":" -f2)
myhours=$(echo $(date "+%H"))
myminutes=$(echo $(date "+%M"))
if [ ${nick_priority} -eq 0 ]
then
if [ ${myhours} -eq ${nick_time_taken_hrs} ]
then
if [ $((${myminutes} - 15)) -gt ${nick_time_taken_minutes} ]
then
kill ${nick_pid}
fi
else
echo �deal with hours�
fi
fi
done