Link to home
Start Free TrialLog in
Avatar of Henry
HenryFlag for France

asked on

Script to summerize the output of errpt command in Unix AIX

Hello,

This is a Shell Script to summerize the output of errpt command in Unix AIX but something wrong :

example.sh :

!/bin/ksh
errpt | awk '{print $1}' | sort | uniq -c | \
        grep -v IDENT > err_.junk
printf "Error \t# \tDescription: Cause (Solution)\n\n"
foreach f (`cat err_.junk | awk '{print $2}'`)
set count = `grep $f err_.junk | awk '{print $1}'`
set desc = `grep $f errs.txt | awk -F '{print $2}'`
set cause = `grep $f errs.txt | awk -F '{print $3}'`
set solve = `grep $f errs.txt | awk -F '{print $4}'`
printf "%s\t%s\t%s: %s (%s)\n" $f $count \
                               "$desc" "$cause" "$solve"
end
rm -f err_.junk


Here is the output error :

./example.sh[5]: 0403-057 Syntax error at line 5 : `(' is not expected.

Thanks for any help
Avatar of noci
noci

This might work better:

!/bin/ksh
errpt | awk '{print $1}' | sort | uniq -c | \
        grep -v IDENT > err_.junk
printf "Error \t# \tDescription: Cause (Solution)\n\n"
for f  in  `cat err_.junk | awk '{print $2}'`
do
  set count = `grep $f err_.junk | awk '{print $1}'`
  set desc = `grep $f errs.txt | awk -F '{print $2}'`
  set cause = `grep $f errs.txt | awk -F '{print $3}'`
  set solve = `grep $f errs.txt | awk -F '{print $4}'`
  printf "%s\t%s\t%s: %s (%s)\n" $f $count \
                               "$desc" "$cause" "$solve"
done
rm -f err_.junk

Open in new window


foreach is a csh format of the command.
Are you sure you want foreach f (`cat err_.junk | awk '{print $2}'`)
and not
for f (`cat err_.junk | awk '{print $2}'`)
?
Avatar of Henry

ASKER

Hello,

Script Shell in Unix AIX (summerize the output of errpt command) :

#!/bin/ksh
errpt | awk '{print $1}' | sort | uniq -c | grep -v IDENT > err_.junk
printf "Error \t# \tDescription: Cause (Solution)\n\n"
for f in `cat err_.junk | awk '{print $2}'`
do
  set count = `grep $f err_.junk | awk '{print $1}'`
  set desc = `grep $f errs.txt | awk -F '{print $2}'`
  set cause = `grep $f errs.txt | awk -F '{print $3}'`
  set solve = `grep $f errs.txt | awk -F '{print $4}'`
  printf "%s\t%s\t%s: %s (%s)\n" "$f" "$count" "$desc" "$cause" "$solve"
done
rm -f err_.junk

The result that I expected is not OK :

Example1               :  ()
Example2               :  ()
Example3               :  ()
Example4               :  ()
Example5               :  ()
Example5               :  ()

Thanks for any help
I have no AIX, but can check ksh...
I have no idea as there is no example of err_.junk
or a few lines of ouput from errpt
i'm not use to ksh, but looks like you forgot a space between the 'f' and the '(' at line 5
@noci
#!/bin/ksh
# Validate existence of following files inside this script:
#	/bin/ls
#	/bin/grep
#	/bin/cat 
#	./errs.txt
#	/usr/bin/awk
#	/usr/bin/sort
#	/usr/bin/uniq
#	/usr/bin/errpt
# If any of them not found replace related locations at your operating system.
# Script creating output to ./err_.junk
# Change ./ to related location if required.
if [ ! -f /bin/ls ]
then
	echo "/bin/ls /bin/ls"
	/bin/ls /bin/ls
elif [ ! -f /bin/grep ]
then
	echo "/bin/grep /bin/grep"
	/bin/ls /bin/grep
elif [ ! -f /bin/rm ]
then
	echo "/bin/ls /bin/rm"
	/bin/ls /bin/rm
elif [ ! -f /bin/cat ]
then
	echo "/bin/cat /bin/cat"
	/bin/ls /bin/cat
elif [ ! -f ./errs.txt ]
then
	echo "/bin/ls ./errs.txt"
	/bin/ls ./errs.txt
elif [ ! -f /usr/bin/awk ]
then
	echo "/bin/ls /usr/bin/awk"
	/bin/ls "/usr/bin/awk"
elif [ ! -f /usr/bin/sort ]
then
	echo "/bin/ls /usr/bin/sort"
	/bin/ls "/usr/bin/sort"
elif [ ! -f /usr/bin/uniq ]
then
	echo "/bin/ls /usr/bin/uniq"
	/bin/ls "/usr/bin/uniq"
elif [ ! -f /usr/bin/errpt ]
then
	echo "/bin/ls /usr/bin/errpt"
	/bin/ls /usr/bin/errpt
else
	# We can also use /usr/bin/sort -u instead of piping to /usr/bin/uniq
	# Including IDENT searching can be handled inside /usr/bin/awk
	/usr/bin/errpt | /usr/bin/awk '{print $1}' | /usr/bin/sort | /usr/bin/uniq -c | \
	/bin/grep -v IDENT > ./err_.junk
	if [ 0 -ne $? ]
	then
		echo "Unable to redirect output to ./err_.junk"
	else
		printf "Error \t# \tDescription: Cause (Solution)\n\n"
		# We can use /usr/bin/awk without /bin/cat handling perfomance issue.
		#for f  in  `/usr/bin/awk '{ print $2}' ./err_.junk`
		for f  in  `/bin/cat ./err_.junk | /usr/bin/awk '{print $2}'`
		do
			#We can use /usr/bin/awk or /bin/sed "s/ .*//;" based on value of $f
			set count=`/bin/grep $f ./err_.junk | /usr/bin/awk '{print $1}'`
			#Use related sepearator when using -F option using /usr/bin/awk
			#set desc = `/bin/grep $f ./errs.txt | /usr/bin/awk -F '{print $2}'`
			set desc=`/bin/grep $f ./errs.txt | /usr/bin/awk '{print $2}'`
			#Use related sepearator when using -F option using /usr/bin/awk
			#set cause = `/bin/grep $f ./errs.txt | /usr/bin/awk -F '{print $3}'`
			set cause=`/bin/grep $f ./errs.txt | /usr/bin/awk '{print $3}'`
			#Use related sepearator when using -F option using /usr/bin/awk
			#set solve = `/bin/grep $f ./errs.txt | /usr/bin/awk -F '{print $4}'`
			set solve=`/bin/grep $f ./errs.txt | /usr/bin/awk '{print $4}'`
			printf "%s\t%s\t%s: %s (%s)\n" $f $count \
			"$desc" "$cause" "$solve"
		done
		if [ -f ./err_.junk ]
		then
			echo /bin/rm ./err_.junk
			/bin/rm ./err_.junk
			if [ 0 -ne $? ]
			then
				echo "Unable to remove ./err_.junk"
			fi
		fi
	fi
fi

Open in new window


output:
$ ./29132408.sh
Error   #       Description: Cause (Solution)

0BA49C99                :  ()
192AC071                :  ()
1BA7DF4E                :  ()
49A83216                :  ()
7F88E76D                :  ()
982C78BF                :  ()
9DBCFDEE                :  ()
A6DF45AA                :  ()
BA431EB7                :  ()
/bin/rm ./err_.junk

Open in new window

please post an example of the input and desired output

my guess is you basically want to filter out an id at col2 and the other columns would contain the same data if col1 contains the same error code.

if the above is true, this can be achieved with either a single and simple awk command or a shell one liner.
... and a bunch of other options such as a while loop
@skullnobrains
Given comment to @noci
or to me ?
@noci
The script was simulated using cygwin (which will work at all OS.
Provide related comment to @skullnobrains
Based on message from TEL2
@noci
Replace:
if [ ! -f /bin/ls ]
then
      echo "/bin/ls /bin/ls"
      /bin/ls /bin/ls
With:
if [ ! -f /bin/ls ]
then
      echo "ls /bin/ls"
      ls /bin/ls
Hi murugesandins,
I think skullnobrains was talking to Henry, not to noci or you.
For people to be willing to complicate their scripts as much as you tend to with all those preliminary tests, there would usually have to be a good reason.  Please explain that good reason to the class.

Can anyone please explain how this "set count = ..." syntax can possibly work in ksh?
    set count = `grep $f err_.junk | awk '{print $1}'`
I've never seen "set" used like that or spacing around the "=".
Shouldn't it be:
    count=`grep $f err_.junk | awk '{print $1}'`

Hi Henry,
Could you please respond to skullnobrains's request above, i.e.
   "please post an example of the input and desired output"

Thanks.
tel2
@TEL2
>> not to noci or you.
:))

>> What is that good reason?
Handle all exceptions when executing any command using $? and report related output / email.
This kind of exception needs to be handled before releasing that script to client/customer/support team.

Tested that only using cygwin (/bin/ksh linked to /bin/mksh).
>> Shouldn't it be:
Hence written the same in given script excluding copied commented lines.
Hi murugesandins,

>> What is that good reason?
> "Handle all exceptions when executing any command using $? and report related output / email.
> This kind of exception needs to be handled before releasing that script to client/customer/support team."

Question #1. Wouldn't it be simpler to let the (short version of the) script crash and detect that in the calling script?  (I can't recall if/how this can be done because I'm out of practice.  Maybe using "eval script.sh" and then do whatever error processing (e.g.. email) based on the return code and STDERR.)

In response to my private message to you, you've replaced this line from your code:
    /bin/ls /bin/ls
with this line:
     ls /bin/ls
Question 2: Doesn't that mean you risk picking up a potentially malicious version of ls, (which I assume is one of your main reasons for using full paths to utilities)?
@TEL2/@noci
Busy at office work.
Hence not written similar code here during that time.
1. Handle following lines inside a function to handle return values.
if [ -f "/bin/ls" ]
then
        LS="/bin/ls"
elif [ -f "/usr/bin/ls" ]
then
        LS="/usr/bin/ls"
else
        echo "Update $0 for location of ls"
        return 1
fi

Open in new window

Even $0 was handle using not to execute that script in current shell.

if [ "-bash" = "$0" ];
then
        echo "Executing murugesandins.sh in current shell not allowed"
elif [ "-ksh" = "$0" ]
then
#like the same handle all related exceptions...

Open in new window

>> script crash and detect that in the calling script
Agreed. Hence handled all exceptions in single script.
It needs to be separated using other script and be handled based on your comment(eval...).
>> which I assume is one of your main reasons for using full paths to utilities
Yes.
> "Agreed. Due to office work handled all exceptions in single script."
Question #3: Why?

Question #4: Why not avoid putting a lot of code (like all those tests at the top of your script) in a lot of scripts by putting a small amount of code in the calling scripts?

You didn't replace:
    /bin/ls /bin/ls
with:
    echo "/bin/ls not found. Update the script having related location of ls"
You replaced it with this:
    ls /bin/ls
Question #5: Right?

Question #6: What is the point in echo'ing this kind of thing:
          echo "/bin/grep /bin/grep"
from line 20 of your script?  How is it helpful for someone to see:
    /bin/grep /bin/grep
in a logfile?  Looks a bit repetitive.
Can you post your updated comment/query again.
@noci
Replace:
      echo "/bin/grep /bin/grep"
      /bin/ls /bin/grep
With:
      echo "/bin/ls /bin/grep"
      /bin/ls /bin/grep
murugesandins,
> "Can you post your updated comment/query again."
Who are you talking to?  Why don't you just refresh your browser?  Try F5.
>>  Due to office work handled all exceptions in single script.
Hence written that script in short time excluding more testing here at cygwin.
@noci/@TEL2
Provide related comments/queries
/bin/cat ~/SetEnv.sh
#!/bin/ksh
if [ "-bash" = "$0" ] || [ "ksh" = "$0" ]
then
	echo "Using SetEnv.sh inside current shell not allowed."
else
	if [ -f /bin/ls ]
	then
		LS="/bin/ls"
	else
		echo "Update $0 using related path to /bin/ls"
		return 1
	fi
	if [ -f /bin/rm ]
	then
		RM="/bin/rm"
	else
		echo "Update $0 using related path to /bin/rm"
		return 3
	fi
	if [ -f ~/errs.txt ]
	then
		ERRFILE=~/errs.txt;
	else
		echo "$LS ~/errs.txt"
		$LS ~/errs.txt
		echo "Update $0 using related path to ~/errs.txt"
		return 5
	fi
	if [ -f /usr/bin/awk ]
	then
		AWK="/usr/bin/awk"
	else
		if [ -f /usr/bin/gawk ]
		then
			AWK="/usr/bin/gawk"
		else
			echo "Update $0 using related path to /usr/bin/awk or /usr/bin/gawk or related location"
			echo "$LS /usr/bin/awk /usr/bin/gawk"
			$LS "/usr/bin/awk /usr/bin/gawk"
			return 6
		fi
	fi
	if [ -f /usr/bin/sort ]
	then
		SORT=/usr/bin/sort
	else
		echo "Update $0 using related path to /usr/bin/sort"
		echo "$LS /usr/bin/sort"
		$LS "/usr/bin/sort"
		return 7
	fi
	if [ -f /usr/bin/uniq ]
	then
		UNIQ=/usr/bin/uniq
	else
		echo "Update $0 using related path to /usr/bin/uniq"
		echo "$LS /usr/bin/uniq"
		$LS "/usr/bin/uniq"
		return 8
	fi
	if [ -f /usr/bin/errpt ]
	then
		ERRPT=/usr/bin/errpt
	else
		echo "Update $0 using related path to /usr/bin/errpt"
		echo "$LS /usr/bin/errpt"
		$LS /usr/bin/errpt
		return 9
	fi
	ERR_JUNK=~/err_.junk
fi

Open in new window

/bin/cat ~/29132408.sh
#!/bin/bash
if [ "-bash" = "$0" ] || [ "ksh" = "$0" ]
then
	echo "Using ~/29132408.sh inside current shell not allowed."
else
	if [ -f ~/SetEnv.sh ]
	then
		. ~/SetEnv.sh
		if [ 0 -eq $? ]
		then
			$ERRPT 2>&1 | $AWK ' 0 == index( $0, "IDENT") {print $1}' | $SORT | $UNIQ -c > $ERR_JUNK
			if [ 0 -ne $? ]
			then
				echo "Unable to redirect output to $ERR_JUNK"
			else
				printf "Error \t# \tDescription: Cause (Solution)\n\n"
				for word  in  `$AWK '{print $2}' $ERR_JUNK`
				do
					export CURWORD="$word"
					count=`$AWK ' 0 != index($0,ENVIRON["CURWORD"]) {print $1}' "$ERRFILE"`
					desc=`$AWK ' 0 != index($0,ENVIRON["CURWORD"]) {print $2}' "$ERRFILE"`
					cause=`$AWK ' 0 != index($0,ENVIRON["CURWORD"]) {print $3}' "$ERRFILE"`
					solve=`$AWK ' 0 != index($0,ENVIRON["CURWORD"]) {print $4}' "$ERRFILE"`
					printf "%s\t%s\t%s: %s (%s)\n" $word $count \
					"$desc" "$cause" "$solve"
				done
				if [ -f $ERR_JUNK ]
				then
					$RM $ERR_JUNK
					if [ 0 -ne $? ]
					then
						echo "Unable to remove $ERR_JUNK"
					fi
				fi
			fi
		fi
	else
		echo "~/SetEnv.sh No such file"
	fi
fi

Open in new window

Tested using simulation at cygwin:
$ ~/29132408.sh
Error   #       Description: Cause (Solution)

0BA49C99                :  ()
192AC071                :  ()
1BA7DF4E                :  ()
49A83216                :  ()
7F88E76D                :  ()
982C78BF                :  ()
9DBCFDEE                :  ()
A6DF45AA                :  ()
BA431EB7                :  ()

Open in new window


$ /bin/cat /usr/bin/errpt
#!/bin/ksh
echo "982C78BF   0930152713 T S mir0           DISPLAY ADAPTER CONFIGURATION ERROR
0BA49C99   0930153113 T H scsi0          SCSI BUS ERROR
0BA49C99   0930153013 T H scsi0          SCSI BUS ERROR
49A83216   0930152913 T H hdisk0         DISK OPERATION ERROR
0BA49C99   0930152913 T H scsi0          SCSI BUS ERROR
0BA49C99   0930152813 T H scsi0          SCSI BUS ERROR
0BA49C99   0930152913 T H scsi0          SCSI BUS ERROR
7F88E76D   0929104913 P S console        SOFTWARE PROGRAM ERROR
9DBCFDEE   0929104613 T O errdemon       ERROR LOGGING TURNED ON
192AC071   0926092513 T O errdemon       ERROR LOGGING TURNED OFF
A6DF45AA   0925162713 I O RMCdaemon      The daemon is started.
1BA7DF4E   0925162713 P S SRC            SOFTWARE PROGRAM ERROR
BA431EB7   0925162713 P S SRC            SOFTWARE PROGRAM ERROR"
$

Open in new window

+1 : @murugesandin : you overcomplicate and end up producing at best much more error porne and less portable scripts.

write that as a single awk. the shell will return false and produce a very explicit error message if awk is missing.

likewise, test for errors on the fly rather than attempt to trap possible errors before they occur : you'll miss some of them and produce wrong information.

example

$ERRPT 2>&1 | $AWK ' 0 == index( $0, "IDENT") {print $1}' | $SORT | $UNIQ -c > $ERR_JUNK
if [ 0 -ne $? ]
                  then
                        echo "Unable to redirect output to $ERR_JUNK"

this is plain wrong : what if uniq segfaults or fails short of memory ? you cannot know the source of the error. what is the point of producing wrong error messages ?

this is MUCH better and easier to read

$ERRPT 2>&1 | $AWK ' 0 == index( $0, "IDENT") {print $1}' | $SORT | $UNIQ -c | tee $ERR_JUNK >/dev/null || exit 1

and additionally the whole logic does not require 12 commands and a temp file
errpt | sed '/IDENT/ d ; s/^[0-9A-Z[:space:]]*//' | sort | uniq -c

i'm cannot type curly brackets with my current keyboard but the awk code would be in pseudo code

<curly>
  agg[$3" "$4" "$5]++;
</curly>
END
<curly>
  for k in agg
    print agg[k]" "k
</curly>
>> and additionally the whole logic does not require 12 commands and a temp file
written the code based on code given by Henry
                 grep -v IDENT > err_.junk
since not sure on Henry's requirement.
!/bin/ksh
errpt | awk '{print $1}' | sort | uniq -c | \
        grep -v IDENT > err_.junk
printf "Error \t# \tDescription: Cause (Solution)\n\n"
for f  in `cat err_.junk | awk '{print $2}'`
do
set count = `grep $f err_.junk | awk '{print $1}'`
set desc = `grep -m1 $f errs.txt | awk -F '{print $2}'`
set cause = `grep -m1 $f errs.txt | awk -F '{print $3}'`
set solve = `grep -m1 $f errs.txt | awk -F '{print $4}'`
printf "%s\t%s\t%s: %s (%s)\n" $f $count \
                               "$desc" "$cause" "$solve"
done
rm -f err_.junk
@skullnobrains
Thank you for the comment
>> since not sure on Henry's requirement.
Example:
Not sure if other script using/verifying err_.junk this file when current script executing using for loop.
Good points, skullnobrains!

But as implied before, aren't your 4 lines like this the wrong syntax?:
    set count = `grep $f err_.junk | awk '{print $1}'`
Shouldn't they be like this?:
    count=`grep $f err_.junk | awk '{print $1}'`

There's also a '#' missing before "!/bin/ksh", in case Henry tries to copy/paste.
oups, i  missed the "set".
you're right they should be removed entirely
and agreed again, i skipped past the shebang

@henry : fix your code an tel2 suggested by removing the "set" useless keywords or pink my one-liner above and you're done.
...and remove the spaces on both sides of the "=" as well.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.