Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Sometimes it is really handy to just add

set -x

to the top of your script to show all commands before they are executed.

There is only one drawback creating scripts with a decent output: I don't know how to add text output to the script this way. If I use

echo 'some comment'

it will result in printing it doubled:

+ echo 'some comment'
some comment

And if I use # it isn't shown at all.

How can I add comments that are printed out like with echo? If I use set -x?

share|improve this question

3 Answers 3

up vote 8 down vote accepted

One hacky way is just to write your comments as arguments to a no-op command. Particularly useful might be the : null utility:

set -x
: Some interesting notes on the following are ...

results in:

+ : Some interesting notes on the following are...

The colon command does nothing, accepts whatever arguments you give it, and always succeeds. You get an extra : at the start of your trace output, but that probably isn't a huge problem for your purpose.

If you don't like the : an even nastier trick is to use a fake command:

set -x
seq 1 1
Some comment &>/dev/null
true

will output:

+ seq 1 1
1
+ Some comment
+ true

That is, the Some comment line is printed out as trace output when the shell tries to run it, but the resulting error message is sent to /dev/null. This is nasty for a lot of obvious reasons, but it also counts as an error for the purposes of set -e.


Note that in either case, your comment is parsed by the shell in the ordinary way, so in particular if you have any special characters they need to be quoted, and because it's trace output the quoting will be displayed.

share|improve this answer
    
Maybe you could create a null function ___ () somehow? to use instead of the : somehow? this would look nicer: ___ some comment –  rubo77 Jul 9 at 12:39
    
@rubo77, sure - if you don't mind the extra obfuscation, you could do ___(): to define a function named ___ that does nothing. –  godlygeek Jul 9 at 13:47

Instead of using "set -x" to print out the debug information, use a separate debug function:

#!/bin/bash

DEBUG=1

debug() {
    if [ $DEBUG == 1 ]
    then
    echo "DEBUG:" $@
    fi
}

debug "foo bar"

Running the script yields

temeraire:ul jenny$ ./testdebug.sh 
DEBUG: foo bar

If you change the assignment to instead read DEBUG=0, it won't print out the line.

share|improve this answer
    
That is another approach, there you would have to define each debug output yourself. for a fast created script it is handy to use set -x so you can write a line before it is executed without writing it twice –  rubo77 Jul 9 at 10:35

I use set -x to debug scripts all the time, and have only ever found the solution that @MichaelHomer suggests which makes use of the null utility (aka. : ..some comment...).

When you're ready to move to a more potent solution I'd suggest implementing your scripts using and actual logger such as log4Bash.

Example

#!/usr/bin/env bash
source log4bash.sh

log "This is regular log message... log and log_info do the same thing";

log_warning "Luke ... you turned off your targeting computer";
log_info "I have you now!";
log_success "You're all clear kid, now let's blow this thing and go home.";
log_error "One thing's for sure, we're all gonna be a lot thinner.";

# If you have figlet installed -- you'll see some big letters on the screen!
log_captains "What was in the captain's toilet?";

# If you have the "say" command (e.g. on a Mac)
log_speak "Resistance is futile";

Results:

   ss #1

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.