Printing snapshot of error of last executed command

Hi everyone,

Hope you are fine and doing great!

I'm trying to get a snapshot of last command output, specially failed one, ie. error code is 1 or greater than 1.

    printlog()
    {
        local status=""
        local errmsg=0

        if [ $1 -eq 0 ]; then
            status="ok"
             ((ALL_INSTALL_COUNT++))
        elif [ $1 -eq 2 ]; then
            errmsg=1
                    status="failed"
        else
            status="failed"
            ((ALL_INSTALL_COUNT++))
            ((FAIL_COUNT++))
        fi

        if [ $errmsg -eq 1 ]; then
             echo -e "<tr><td>$2</td><td width='10%' align='right'>$status</td></tr>"
        else
             echo -e "<tr><td>$2</td><td width='10%' align='right'>$status</td></tr>"

        fi
    }

suppose the below command will error out because no directory is present

ls -lrt /scratch_b/mannu39

The output will be

ls: cannot access /scratch_b/mannu39: No such file or directory

If I executed using the function

ls -lrt /scratch_b/mannu39
printlog $? "checking directory"

Output would be

ls: cannot access /scratch_b/mannu39: No such file or directory
<tr><td>checking directory</td><td width='10%' align='right'>failed</td></tr>

What I'm trying is to get the snapshot of error to be printed as well. In the current example it's just 1 line but for some commands it might be more than few lines so snapshot would take upto 5 lines from the tail to get the error.

output would be like-

<tr><td>checking directory</td><td width='10%' align='right'>failed</td><td>ls: cannot access /scratch_b/mannu39: No such file or directory</td></tr>

Please help.

how about ...

#!/usr/bin/bash
    printlog()
    {
        local status=""
        local errmsg=0

        if [ $1 -eq 0 ]; then
            status="ok"
             ((ALL_INSTALL_COUNT++))
        elif [ $1 -eq 2 ]; then
            errmsg=2
                    status="failed"
        else
            status="failed"
            ((ALL_INSTALL_COUNT++))
            ((FAIL_COUNT++))
        fi

        if [ $errmsg -eq 1 ]; then
             echo -e "<tr><td>$2</td><td width='10%' align='right'>$status</td></tr>"
        else
             echo -e "<tr><td>${2}</td><td width='10%' align='right'>failed</td><td>${3}</td></tr>"

        fi
    }
err="$(ls /foo 2>&1)"
printlog $? "checking directory" "${err}"
1 Like

Thanks but running the command and store standard input and output in a variable doesn’t seems feasible. For example if we run a make command or sudo yum install any package, there are too many lines and don’t want to run everything through a variable. Printlog function should be standalone that will work with any command. That’s why idea would be to have a generic function that can do what expected and capture only 4-5 lines from tail to avoid ugliness in the variable for reading.

yeah, it is ugly - agreed.
Another idea might be.... redirect ALL error output of a script to a log file.
And have your printLog function "tail -4" of a file each time $? -ne 0.
The you'll have to take care of the "over-lapping" log lines for say commands that produce less then 4 lines of errors.

Others might have other ideas....

P.S. a better question is why do you want to do this?
If you care only about errors, redirect stdout to /dev/null, and your stderr will appear only in the log file and "screen" to observe/record.
You can implement another enhancement to determine if there's no "terminal" associated with stdout/stderr (e.g. invoked cron) and not output anything to a "screen" - only the log file.

1 Like

I have tried the way you recommended - Implement in a different fashion, break the log file for every command and use to grep the last few lines - that’s working but makes code bit messy, my purpose was to dump the data in the database and pull out via BI tools to make a structure reporting of all the failed scenarios with some minimal lines of reason “Why the command got failed” I hope you understand the purpose now. I was just trying to be more generic, portable and simple so that none of the other code block has been changed or impacted.

I Googled a bit and found a number of hits - including this one and this one. I'm sure there're others. If your script(s) are using more modern bash, then I think your options might be wider.
I guess it all depends on how non-messy you want to stay and what your tolerance level is :wink:

1 Like

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.