15

I would like to write a bash script the prints the commands. But for readability purposes, I do not want it to print the echo commands. Unfortunately, I cannot find the correct settings for my bash script to achieve this. I need help?

#!/bin/bash

# Makes the bash script to print out every command before it is executed
set -v

echo "Cleaning test database"
RAILS_ENV=test bundle exec rake db:drop
echo "************************************************************"
echo ""

echo "Setting up the test database"
RAILS_ENV=test bundle exec rake db:setup
echo "************************************************************"
echo ""

The output looks like:

echo "Cleaning test database"
Cleaning test database
RAILS_ENV=test bundle exec rake db:drop
echo "************************************************************"
************************************************************
echo ""


echo "Setting up the test database"
Setting up the test database
RAILS_ENV=test bundle exec rake db:setup

As you can see it prints out all the commands including the echo command, which I do not want to see.

2
  • 1
    Maybe this?: | grep -v "echo " Commented Oct 29, 2015 at 10:36
  • Would a Makefile be appropriate for your task? It's a wildly different approach, but make echoes each command by default as it executes it, unless you prefix the command with @. Commented Oct 29, 2015 at 11:58

2 Answers 2

18

You could use trap DEBUG instead of set -v as one option.

For example

#!/bin/bash


# Makes the bash script to print out every command before it is executed except echo
trap '[[ $BASH_COMMAND != echo* ]] && echo $BASH_COMMAND' DEBUG

echo "Cleaning test database"
RAILS_ENV=test bundle exec rake db:drop
echo "************************************************************"
echo ""

echo "Setting up the test database"
RAILS_ENV=test bundle exec rake db:setup
echo "************************************************************"
echo ""

Debug is executed after every command.
$BASH_COMMAND is currently running command.

BASH_COMMAND The command currently being executed or about to be executed, unless the shell is executing a command as the result of a trap, in which case it is the command executing at the time of the trap.

So the trap just checks if the last command did not start with echo and prints it.

Sign up to request clarification or add additional context in comments.

5 Comments

Thx 123, it works great and I will use it. It is an interesting approach which I had not thought about. I wonder if there are special options or settings for my problem.
@GerardoNavarroSuarez I don't think there are, but if you find any let me know!
thanks @123. What if I want to hide other prints, like "read -s ...". I couldn't find the correct || && syntax...
ohh, no dealing with || is required... this works: trap '[[ $BASH_COMMAND != echo* ]] && [[ $BASH_COMMAND != read* ]] && echo $BASH_COMMAND' DEBUG
I found that ´pwd´ is printed as ´pwd´ when using this DEBUG solution. When using -x the actual value is printed. I need to know the later.
6

Thanks @123 !

To filter multiple strings from the DEBUG trap (not just echo commands), we can use regexp match too.

For example, to filter out any command that starts with "echo" or "read" or "if", I use:

trap '! [[ "$BASH_COMMAND" =~ ^(echo|read|if) ]] && echo $PS4$BASH_COMMAND' DEBUG

Update:

In order to show bash ${variable} values expended, I now use:

trap '! [[ "$BASH_COMMAND" =~ ^(echo|read|if) ]] && \
cmd=`eval echo "$BASH_COMMAND" 2>/dev/null` && echo "$cmd"' DEBUG

2 Comments

You command works but it still prints echo messages. I have tired trap '! [[ "$BASH_COMMAND" =~ ^(echo|read|if|sleep|confirm_and_exit_on_no|confirm|exit) ]] && \ cmd=`eval echo "$BASH_COMMAND" 2>/dev/null` && echo ---- "$cmd" ----' DEBUG
@abhiarora, note two things: The ^ char means it will look for the begining of a line only, so if the echo is not at the beginning of a line, it will print it. Also note the \ char, it is required only if you break a long line in bach script, so remove it if you you dont use multiline for this script.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.