Bash – How to print only certain commands from a bash script as they are run

bashscriptingshell-script

I have a bash script with various if statements based on command line arguments I pass in when calling it. Having some kind of output as to what commands are being run is helpful to confirm the flow through all those if statements, but my current solution is giving me too much information.

Using set -v in the script was somewhat helpful to see commands printed to the screen as they were run in the script, however I get too many commands. It's almost like an entire copy of the script.

I want output that shows what commands are being run, but I don't want to see comments, new lines, expressions in if statements, etc.

Is there a way I can pass all possible output generated by the -v option through a regex first before being printed? Or some other solution to get bash to only output commands of a certain "type" (e.g. that are using executables and not just bash specific statements, comments etc.?)

[1] https://stackoverflow.com/questions/257616/sudo-changes-path-why was quite helpful on this and is where I got the suggestion for the set -v usage.

Edit:

A similar (but not identical) script to the one I'm running:

#!/bin/bash

#get verbose command output
set -v

env=$1

if [ "$env" == "dev" ]; then
    python ascript.py
fi

if [ "$env" == "prod" ]; then

    #launching in prod will most likely fail if not run as root. Warn user if not running as root.
    if [ $EUID -ne 0 ]; then
        echo "It doesn't look like you're running me as root. This probably won't work. Press any key to continue." > /dev/stderr
        read input
    fi

    #"stop" any existing nginx processes
    pkill -f nginx

    nginx -c `pwd`/conf/artfndr_nginx.conf

fi

I want only 2 possible sets of output lines from this script. The first:

python ascript.py

The second:

pkill -f nginx
nginx -c /some/current/directory/conf/artfndr_nginx.conf

Best Answer

When I write more complex bash scripts, I use a little function to run commands that will also print the commands run into a logfile:

runthis(){
    ## print the command to the logfile
    echo "$@" >> $LOG
    ## run the command and redirect it's error output
    ## to the logfile
    eval "$@" 2>> $LOG 
}

Then, in my script, I run commands like this:

runthis "cp /foo/bar /baz/"

If you don't want a command printed, just run it normally.

You can either set the $LOG to a filename or just remove it and print to stdout or stderr.

Related Question