I don't like the `require_curl` example.<p>Here's what is done there:<p><pre><code> OK=0
FAIL=1
function require_curl() {
which curl 2>&1 > /dev/null
if [ $? -eq 0 ]
then
return $OK
fi
return $FAIL
}
</code></pre>
(`2>&1 > /dev/null` drops stdout and writes stderr to stdout—not what was meant. `which` doesn't write to stderr, so I drop that part.)<p>That can be shortened significantly by using the return code directly in the if branch:<p><pre><code> function require_curl() {
if which curl > /dev/null
then
return $OK
fi
return $FAIL
}
</code></pre>
Or by just using the return code directly:<p><pre><code> function require_curl() {
which curl > /dev/null
return $?
}
</code></pre>
And as it will return the return code of the last statement executed:<p><pre><code> function require_curl() {
which curl > /dev/null
}</code></pre>
My eyes bleed. So many unquoted expansions!<p><pre><code> APP_ROOT=`dirname $0`
filename=`basename $filepath .html`
</code></pre>
should read:<p><pre><code> APP_ROOT=`dirname "$0"`
filename=`basename "$filepath" .html`
</code></pre>
Plus if your script supports both `--version` and `--help` with proper formats, you can easily generate a manual page with `help2man`. The help output example is far from that. Also, he does not mention getopt at all.<p>The magic line for that is:<p><pre><code> eval "set -- $(getopt -o hV -l help,version -- "${@}")" || exit $?
echo "${*}"
</code></pre>
It does this:<p><pre><code> $ ./test foo bar --help --version
--help --version -- foo bar
</code></pre>
Which can be parsed using a `while` loop with `shift`.<p>For other tips on shell scripting best practices I recommend Gentoo ebuilds. They tend to be quite well written. And always read scripts from other people before running them yourself.
Shell scripts have their use but at the point when your script needs output coloring or printing debug information, it is time to switch to Python.<p>Edit: Place a general disclaimer to weaken the absolute tone of the above statement. Rule of thumb, exceptions apply, yadda, yadda. In other words, I somewhat agree with most responses that disagreed with the statement above :-)
Huh, no mention of "set -e -u"?
Do yourself a favor and follow this, too:
<a href="http://www.davidpashley.com/articles/writing-robust-shell-scripts/" rel="nofollow">http://www.davidpashley.com/articles/writing-robust-shell-sc...</a>
A good gem I found recently was to use the big version of the command line flags. So instead of seeing -s -q 1, you should use arguments like --max-depth. Increases the readability of scripts by a huge margin.
My favorite discovery is how to efficiently do RPC style calls in BASH. Let's say you have some functions and variables you want to execute on a remote server. Just do the following:<p><pre><code> ssh remotehost "
$(declare -p var1 var2 var3)
$(declare -f func1 func2 remotemain)
remotemain"
</code></pre>
In this example, var1, var2, var3 and func1, func2 are support variables/functions for the function "remotemain". This pushes all those to the remote side, then calls remotemain.
A while ago I was working on a bash function library. The library itself may not be that usefull but it also contains some examples on how to color output and move the cursor around. <a href="http://code.google.com/p/bsfl/" rel="nofollow">http://code.google.com/p/bsfl/</a>
<p><pre><code> function require_curl() { which "curl" > /dev/null; }
function require_curl() { which -s "curl"; }
function debug { ((DEBUG)) && echo ">>> $*"; }
</code></pre>
Last one is bash, which -s is BSD'ish
As someone who is learning PHP as his first programming language, I am surprised to see similarity in terms to syntax with shell scripts. Are there other popular language with php-like sytax?
Shell scripts frequently fail to handle directory names with spaces in them. Example from the linked article:
APP_ROOT=`dirname $0`<p>This is not going to do what you expect if the current script is run via a command with spaces in one of the preceding directories' name.<p>It should be:
APP_ROOT="`dirname "$0"`"<p>Even this would fail if your immediate parent directory's name ended with a newline character, but should handle any other whitespace without issue.
Browse this website and you will learn a lot about bash. Opinionated at times, but that's what I like. If you use Bash scripting you've might encountered this site already, but for what it's worth:
<a href="http://mywiki.wooledge.org/BashFAQ" rel="nofollow">http://mywiki.wooledge.org/BashFAQ</a>
I wrote a silly script for noob openbsders like yours' truly: it builds the usage from functions' comments in the script on-the-fly. <a href="https://gist.github.com/6120072" rel="nofollow">https://gist.github.com/6120072</a>
Might inject those `tput` color commands into my shell<p>To those curious: <a href="https://github.com/jalcine/dotfiles" rel="nofollow">https://github.com/jalcine/dotfiles</a>
All this article does is make me wish there were an alternative to typical Borne shell garbage. No sane person would ask for a wretched pile of hacks like this.