1

During the process of writing a script, I will use the command's output in varying ways, and to different degrees - in order to troubleshoot the task at hand.. For example, in this snippet, which reads an Application's icon resource and returns whether or not it has the typical .icns extension...

icns=`defaults read /$application/Contents/Info CFBundleIconFile`
    if ! [[ $icns =~ ^(.*)(.icns)$ ]]; then
        echo -e $icns "is NOT OK YOU IDIOT!  **** You need to add .icns to "$icns"."
    else 
        echo -e $icns "\t Homey, it's cool.  That shits got its .icns, proper."
    fi

Inevitably, as each bug is squashed, and the stdout starts relating more to the actual function vs. the debugging process, this feedback is usually either commented out, silenced, or deleted - for obvious reasons.

However, if one wanted to provide a simple option - either hardcoded, or passed as a parameter, to optionally show some, all, or none of "this kind" of message at runtime - what is the best way to provide that simple functionality? I am looking to basically duplicate the functionality of set -x but instead of a line-by rundown, it would only print the notifications that I had architected specificically.

It seems excessive to replace each and every echo with an if that checks for a debug=1|0, yet I've been unable to find a concise explanation of how to implement a getopts/getopt scheme (never can remember which one is the built-in), etc. in my own scripts. This little expression seemed promising, but there is very little documentation re: 2>$1 out there (although I'm sure this is key to this puzzle)

[ $DBG ] && DEBUG="" || DEBUG='</dev/null'
check_errs() {
    # Parameter 1 is the return code Para. 2 is text to display on failure.
    if [ "${1}" -ne "0" ]; then
        echo "ERROR # ${1} : ${2}"
    else
        echo "SUCESSS  "
    fi }

Any concise and reusable tricks to this trade would be welcomed, and if I'm totally missing the boat, or if it was a snake, and it would be biting me - I apologize.

Alex Gray
  • 16,007
  • 9
  • 96
  • 118
  • 1
    Good post, but am confused by your statement 'very little doc. re: `2>$1`... I'm sure this is the key to the puzzle'. I don't see `2>$1` anyplace else in your post, do you mean `2>&1`? The test and following function at the end of your post seems like a pretty good debugging technique per your requirments. `DBG=true` ought to turn on debugging, right? It is hard to see where DEBUG is being used, assuming it was set. Finally, don't forget that you can prefix your script with envVar settings on the command line, i.e. `DBG=true ./myScript.sh file1 ...`. That is my workaround for getopt Good Luck. – shellter Jul 29 '11 at 19:00
  • Yes, that's what I mean, `2>$1`.. It's a "new feature" as of bash4, I believe, so all I ever see written about it is usually grumpiness that something has changed.. And yes, that test for DBG was the idea.. Does it require using `2>&1` after each line that I may, or may not want printed? What is `2>&1` anyways? Is it like `=>` in php... an all important and pervasive lingual keystone - that remains nameless? It's a shame that google is so useless when searching for anything but words! Google should make a deal with SO to use their symbol search algorithm... it's much better! – Alex Gray Jul 29 '11 at 20:24
  • @alex gray: It's still not clear which you want 2>$1 or 2>&1. Did you make the typo again in your comment? – grok12 Jul 29 '11 at 22:15
  • Well, the string `>$` doesn't show up on the bash4 man page. (I also tried searching for `>$1`). As I don't have access to bash4, I would recommend constructing some small tests. In other cases `$1` is the first cmdline param, so make a test to try redirecting output into a variable named file (i.e. `$1`), and see if it works. – shellter Jul 29 '11 at 23:39
  • d'oh. yes, i meant 2>&1. it just makes no sense to me, looking at.. it's no wonder i can't manage to type it right. [seems like I'm not the only one.](http://stackoverflow.com/questions/818255/in-the-bash-shell-what-is-21) Looks like to the top answerer originally mistyped it too, lol. I'll take a look at the references there to try to get my head around it. I find that no matter how many times an abstract construct like that is explained to me, I'll never be able to use/remember/like it unless I actually can figure out what it's doing. – Alex Gray Jul 30 '11 at 00:49
  • Back again. `2>&1` is shell redirection syntax. I only know the typical cases, (and this is example #1!), `2` (in this context with the `>&1`) is the stderr output, so by adding the remainder, you are saying 'tie the stderr output to the same filestream used by file stream 1 (`&1`)', or more succiently 'redirect stderr output to same place as stdout'. The 2nd most common use of output redirection is `>/dev/null 2>&1`, which says first, send all stdout output to /dev/null (effectively discarding it) AND also 'send stderr output to the same place as stdout'. – shellter Aug 05 '11 at 03:58
  • Finally, the 3rd most common, is to redirect stdout to stderr, i.e. 'echo Error >&2`, which would be helpful for you and your debugging tools. Good luck! – shellter Aug 05 '11 at 04:05

2 Answers2

1

One easy trick is to simply replace your "logging" echo comamnd by a variable, i.e.

TRACE=:
if test "$1" = "-v"; then
    TRACE=echo
    shift
fi

$TRACE "You passed the -v option"

You can have any number of these for different types of messages if you wish so.

pyroscope
  • 4,120
  • 1
  • 18
  • 13
0

you may check a common open source trace library with support for bash.

WKR

Arno-Can Uestuensoez

acue
  • 381
  • 3
  • 6