Formatting the output of ps -eo command

Hi ive been tasked to create a warning email which will be sent when a process exceeds a given percentage of CPU,
Ive created the script where it runs:

ps -eo pri,pid,user,nice,pcpu,comm  | awk '{if($5 >= 2)print $0}' >> /export/home/tjmoore/file2 2>/dev/null

I would then run a mail program to email it to me, This all works fine however I would like to format how it is displayed when it comes through on email,

This is currenlty what Im getting:

PRI   PID     USER    NICE    %CPU    COMMAND
 50 13109     root 20  3.0 _progres
  0  9838     root 20 10.8 _progres
 59  5790     root 20  4.1 _progres

Its looking a bit messy, can anyone help?

Try setting the output field separator to, say, <TAB>:

awk 'OFS="\t" {$1=$1; if($5 >= 2) print}'

Don't forget to address some field (e.g. $1=$1) so $0 is recreated...

If that doesn't work try printf

Given it ago but it doesnt seem to be working this is the script as it stands:

#!/bin/bash
#Send process which has exceeded 5%
#
#
echo 'The below is a list of processes which have exceeded the 5% threshold' >
/export/home/tjmoore/file2
#
echo ' ' >> /export/home/tjmoore/file2
#
echo 'PRI    PID     USER    NICE    %CPU    COMMAND' >> /export/home/tjmoore/fi
le2
#
if ps -eo pri,pid,user,nice,pcpu,comm | awk 'OFS="\t" {if($5 >= 2); $1=$1; print
 $0}' >> /export/home/tjmoore/file2 2>/dev/null
#
then /usr/local/bds/mailsend.s mailx "Process has surpassed 25% threshold" <email address> <email address> /export/home/tjmoore/file2 2&1>/dev/
null
fi
#

---------- Post updated at 09:40 AM ---------- Previous update was at 09:17 AM ----------

sorry I am a novice at scripting, $1=$1 means argument 1 = argument 1?
What do you mean by:

Don't forget to address some field (e.g. $1=$1) so $0 is recreated...

Many Thanks for your help with this

Sorry, I'm not sure I understand what you really want. The original question was on formatting; is that settled by now?
The script in your second post doesn't seem to work as expected - which might be phrased as "send a mail if that output files contains >=1 lines". If that's the case, we need awk to issue an exit code according to its success. As I'm not sure what intrinsic codes it sends, try this in your if statement:

ps ...  | awk  '{if($5>=2) {$1=$1; found=1; print}} END {exit !found}' OFS="\t"

And yes, $1=$1 means field 1 = field 1, which is a dummy assignment that causes $0 to be modified and thus recreated. If $0 is not recreated, the <TAB> OFS will not be inserted.

Thankyou for your persistance with this

I dont seem to be getting any email through anymore so I can't see if the formatting has worked or not

 
#!/bin/bash
#Send process which has exceeded 25%
#
#
echo 'The below is a list of processes which have exceeded the 25% threshold' >
/export/home/tjmoore/file2
#
echo ' ' >> /export/home/tjmoore/file2
#
echo 'PRI PID USER NICE %CPU COMMAND' >> /export/home/tjmoore/fi
le2
#
if ps -eo pri,pid,user,nice,pcpu,comm | awk '{if($1>=2) {$1=$1; found=1; print}}
END {exit !found}' OFS="\t" >> /export/home/tjmoore/file2 2>/dev/null
#
then /usr/local/bds/mailsend.s mailx "Process has surpassed 25% threshold" <email address> <email address> /export/home/tjmoore/file2 2&1>/dev/
null
fi
#

---------- Post updated at 04:35 AM ---------- Previous update was at 04:32 AM ----------

Ive altered the percentage CPU the process has to use to be picked up just so I can be sure I will be getting some results, I will alter back when the script works

OK, so we have to analyze stepwise. Any error messages?
The if statement needs a ; before the then part.
To check the logics of the awk stmt,please repeatedly run

ps ...|awk '{if($5>=2) {$1=$1; found=1; print}} END {exit !found}' OFS="\t"; echo "exit code: "$?

and increase the percentage x ($5>=x) until no line is printed any more. How does the exit code change?

1 Like

Ive used the code you supplied and get this response, Ive substituted x with numbers 1-10

awk: syntax error near line 1
awk: illegal statement near line 1
exit code: 2

Strange ... if I do (disregard me testing $1 instead of $5) result is:

# ps |awk '{if($1>=5) {$1=$1; found=1; print}} END {exit !found}' OFS="\t"; echo "exit code: "$?  
5       S       root    972     1       ...
5       S       root    1504    1       ...
exit code: 0
# ps |awk '{if($1>=6) {$1=$1; found=1; print}} END {exit !found}' OFS="\t"; echo "exit code: "$?
exit code: 1

So my awk version must differ from yours. What be your version? And - please split all the awk commands into separate lines like

ps ...  |awk '
{if($5>=2)
 {$1=$1;
  found=1;
   print}}
END {exit !found}'

so we'll get an indicator on what's wrong.

1 Like

Sorry may sound dumb but how to you find out the version of

awk

you are using?

And Ive broken the code down into seperate lines as suggested above and received this response

awk: syntax error near line 6
awk: illegal statement near line 6

Try awk -W version . And then, read your awk's man page about the exit command. Here's an excerpt from mine:

found this in the man pages for awk

exit [expr]     # skip the rest of the input; exit status is expr

cant find the version though using your code above

one - try exit found (=leave out "!") so we find out if it doesn't like the negation
two - the man page should give you an indication on how to output the version

ive looked thorugh the man pages and cant find anything on how to tell which version of awk im using however I did see a mention of POSIX locale if that heps at all.

Im now getting the following so it seems to be working just need to get it to put a tab space and not the backslash between fields

ps -eo pri,pid,user,nice,pcpu,comm | awk '{if($5>=5) {$1=$1; found=1; print}} END {exit found}' OFS="\t"; echo "exit code: "$? 
20\10833\root\20\12.4\/apps/progress//bin/_progres
30\14631\root\20\10.7\_progres
20\19628\root\20\10.5\_progres
exit code: 1

OK, we're getting there. Looks like your awk is a bit delicate. Modify your awk line like

awk 'BEGIN {found=1} {if($5>=5) {$1=$1; found=0; print}} END {exit found}' OFS="        ";

Make sure to enter a <TAB> char for OFS, in the shell (bash!?) by prepending it with <CTRL>V (or do it in an editor).

yes we are, right this is the script as it stands, it sends an email now but only with the content I have echoed in before the awk command.

echo 'PRI    PID     USER    NICE    %CPU    COMMAND' >> /export/home/tjmoore/fi
le2
#
if ps -eo pri,pid,user,nice,pcpu,comm |awk 'BEGIN {found=1} {if($5>=5) {$1=$1; f
ound=0; print}} END {exit found}' OFS=$'\t'; >> /export/home/tjmoore/file2 2>/de
v/null
#
then /usr/local/bds/mailsend.s mailx "Process has surpassed 5% threshold" <email address> <email address> /export/home/tjmoore/file2 2&1>/dev/n
ull
fi
#

the actual ps ... output is displayed on the terminal screen and doesnt append to the file which I tell it to

As stated before, you need to append a ; to the if statement, i.e. right before the then statement; I'm surprised there was no error msg.
Does the OFS=$'\t' do what it's meant to do, assign the <TAB> char you need in the output?

Just for the current, don't suppress errors, 2>/dev/null , let it show its errors!

1 Like

Im away from the system now Ill try this tomorrow, the tab output is working great now yeah

---------- Post updated 03-08-12 at 04:31 AM ---------- Previous update was 02-08-12 at 10:03 AM ----------

Looks like it is all working perfectly now! :slight_smile:

cheers RudiC, I appreciate all the help you have provided

Finishing Script:

#!/bin/bash
#Send process which has exceeded 5%
#
#
echo 'The below is a list of processes which have exceeded the 5% threshold' > /
export/home/tjmoore/file2
#
echo ' ' >> /export/home/tjmoore/file2
#
echo 'PRI         PID         USER      NICE    %CPU    TIME     COMMAND' >> /ex
port/home/tjmoore/file2
#
if ps -eo pri,pid,user,nice,pcpu,time,comm |awk 'BEGIN {found=1} {if($5>=5) {$1=
$1; found=0; print}} END {exit found}' OFS=$'\t' >> /export/home/tjmoore/file2;
then /usr/local/bds/mailsend.s mailx "Process has surpassed 5% threshold" <email address> <email address> /export/home/tjmoore/file2 > 2&1>/dev
/null
fi
# 

I love it when a plan comes together

1 Like

hi, just looking at th script so I can learn and understand every part of it for future scripting, what does the

{found-1}

and

exit found

do?

In your post #11 you said you found exit [ expr ] in your awk's man page. That's exactly what we are using here: exit found conveys awk's success or failure as its "exit status" to the shell for evaluation in the if construct, 0 representing success and 1 representing failure.
BEGIN {found=1} initialises the status to failure, but any line with percentage ($5) matching or exceeding 5 will set {found=0} , maybe repeatedly, so the conveying works.

1 Like