Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Better way to make a bash script self-tracing?

I have certain critical bash scripts that are invoked by code I don't control, and where I can't see their console output. I want a complete trace of what these scripts did for later analysis. To do this I want to make each script self-tracing. Here is what I am currently doing:

#!/bin/bash
# if last arg is not '_worker_', relaunch with stdout and stderr
# redirected to my log file...
if [[ "$BASH_ARGV" != "_worker_" ]]; then
    $0 "$@" _worker_ >>/some_log_file 2>&1  # add tee if console output wanted
    exit $?
fi
# rest of script follows...

Is there a better, cleaner way to do this?

like image 707
Kevin Little Avatar asked Mar 13 '10 20:03

Kevin Little


People also ask

How do I trace a shell script?

Shell tracing simply means tracing the execution of the commands in a shell script. To switch on shell tracing, use the -x debugging option. This directs the shell to display all commands and their arguments on the terminal as they are executed.

How do I get the full path of a bash script?

In this case, first, we need the current script's path, and from it, we use dirname to get the directory path of the script file. Once we have that, we cd into the folder and print the working directory. To get the full or absolute path, we attach the basename of the script file to the directory path or $DIR_PATH.

How do I run a full path in a shell script?

To use full path you type sh /home/user/scripts/someScript . sh /path/to/file is different from /path/to/file . sh runs /bin/sh which is symlinked to /bin/dash . Just making something clear on the examples you see on the net, normally you see sh ./somescript which can also be typed as `sh /path/to/script/scriptitself'.

How will you make sure only one instance of a shell script can run?

We can use the parameter -n to use flock in a non-blocking way. This will make flock immediately exit with an error when there is another lock on the file. We should use -n if we don't want the script to run a second time in the event that it's already running.


2 Answers

#!/bin/bash
exec >>log_file 2>&1

echo Hello world
date

exec has a magic behavior regarding redirections: “If command is not specified, any redirections take effect in the current shell, and the return status is 0. If there is a redirection error, the return status is 1.”

Also, regarding your original solution, exec "$0" is better than "$0"; exit $?, because the former doesn't leave an extra shell process around until the subprocess exits.

like image 143
Kevin Reid Avatar answered Sep 22 '22 08:09

Kevin Reid


maybe you are looking for set -x?

like image 36
Anycorn Avatar answered Sep 22 '22 08:09

Anycorn