1

As is known, we can redirect errors to a specific file with:

./some_script 2>error_log

I am running multiple scripts, and would like them to put their errors into a single error file.

Is there any way to append information, such as script name, in front of each error instance? That way the error log could note, for instance, the script name that is posting the error etc.

john-jones
  • 1,736
  • 1
    Related: https://unix.stackexchange.com/q/157689/117549 – Jeff Schaller Nov 02 '19 at 15:08
  • what would really solve it, is if we could start piping the file descriptor redirection. ./some_script 2 | printf "error_appendation_here"+stream >> error_log. I've never heard of that being done though. – john-jones Nov 02 '19 at 15:15

2 Answers2

3

Create an error log function for your scripts. Something like:

logerr () {
    printf '%s - %s - %s\n' \
    "$(date '+%F:%T')" \
    "$(basename "$0")" \
    "$*" >&2
}

Then you call that from your scripts like:

if false; then
    : something for pass
else
    logerr failed to be false
fi

Also using 2>error_log will overwrite error_log every time. You need to use 2>>error_log to append.


If you want to be able to capture errors from other commands and error log them you could hack together something like this:

#!/bin/bash

logerr () {
    local message=$*
    if [[ ! -t 0 ]]; then
        message=$(</dev/stdin)
    fi
    if [[ -n "$message" ]]; then
        printf '%s - %s - %s\n' \
        "$(date '+%F:%T')" \
        "$(basename "$0")" \
        "$*" >&2
    fi
}

ls -lts /fake/path 2>&1 >/dev/tty | logerr

Ensuring you redirect stdout to whatever applicable location you need it at.

This will allow the logerr script to read from stdin if it is open (allowing you to pipe programs into logerr). The problem is the programs will send error messages to stderr and you want that to remain separate from stdin.

jesse_b
  • 37,005
  • So the else gets executed if there is an error in the current process/script. So I just put that in the beginning of each script that intends to log to the error file. – john-jones Nov 02 '19 at 14:58
  • No this function would have to be used in each script at every place where the script logs errors. – jesse_b Nov 02 '19 at 14:59
  • Is there no way to say, "if this script has an error, add this infront of that error message"? – john-jones Nov 02 '19 at 15:02
  • @HermannIngjaldsson: There may be but I think no matter what you are going to find that error logging isn't a very simple task. The more verbose you want your logs to be the more manual error handling you will need to program into your code. – jesse_b Nov 02 '19 at 15:05
0
./thescript.sh 2>&1 1>/dev/null | sed '1 s/^/error_message_starts:\n/' >> error_log;

Built on the discussion here plus this:
https://stackoverflow.com/questions/2342826/how-to-pipe-stderr-and-not-stdout

In order to add whatever we want. We need to be able to pipe error stream (fd2). The only pipeable output is fd1. So fd2 needs to be redirected to fd1. We also must rid of fd1 so it doesnt get in the way.

  • ./thescript.sh
  • 2>&1 Error stream(fd2), goes to whatever fd1 goes to.
  • 1>/dev/null. Fd1 just goes off a cliff. Now only the error log (fd2), get piped.
  • | sed.. Do the piping into sed that adds that thing infront.
  • >> error_log Append the stream to an error log
john-jones
  • 1,736