Coder of Salvation™   — programming / opensource / console / minimal

Shellscripting the fast way


Shellscript allows you to mashup all programminglanguages at once, so learning it as a swiss armyknife really pays off in the longterm

Especially when developing with vim or emacs, the testing/implementing-cycle is really fast, since you can execute shellscripts from the editor itself.

Why a framework is handy

Check out the minimal shellscript framework below, which I found to be very very productive. It was inspired by monkeytail After developing a bit with it, I discovered the snippet below is an extract of its magic.


    grep "^[^_].\+(){$" $0 | while read line; do 
      echo "  $0 $line" | sed "s/().*//g"; 
    echo "";

  echo "executing foo!"

# run arguments as commands if any, or show Usage
if [ ${#1} == 0 ]; then echo "$CMDS" | echo "Usage: "; _usage; fi


Ok, basically you have private functions (starting with an underscore) and public functions. The script will list the available public functions (which are commands) by default (if no argument is given). So on the commandline you can do:

$ chmod 755 myshellscript 
$ ./myshellscript 
    myshellscript foo

$ myshellscript foo
executing foo!

Nitro inside your editor

Shellscripts turns vim/emacs/etc into a IDE without any problems. For example, in vim you can do:

:!./%          <-- runs current script as external command 
    myshellscript foo
:!./% foo
executing foo!
:!man curl     <-- gives manual about curl command 
:!read --help  <-- gives manual about read command

Fast workflow

The development workflow mentioned above can really improve your productivity. The shellscript language can be very picky about spaces and ';' signs, but it really pays off when you get the hang of it, and start using functions. You can start mixing all languages right away:

  local msg=$1
  local foo=$(perl -e "$msg"); 
  local bar=$(php -r "echo md5('$msg');")
example "this is a message"


Automatic documentation

We could also extend our framework with autodocumentation. In the following example we supply a comment for every funtion, and a modified _usage() function.

# this will echo 'hello world'
  echo "hello world"
  grep "^[^_].\+(){$" $0 | while read line; do
    local cmd=$(echo "$line" | sed "s/(){//g")
    local info=$(grep -C0 -A0 -B1 "$cmd(){" $0 | sed "N;s/\n.*//g" )
    printf "    $0 %-20s %-40s\n" "$cmd" "$info" | grep "#"
  done; echo "";


$ ./myshellscript
    ./myshellscript foo         # this will echo 'hello world'

Check requirements

It would be sad if people get all excited about a shellscript, to find out it doesnt work on their system. Therefore, lets be very serious about it in advance. Lets check if our commands are available like this:

requirements="sed grep printf cut sort php echo clear"
  for req in $requirements; do
    hash "$req" 2>&-
    if [ $? == 1 ]; then echo "please install '$req'"; exit; fi

Embed a manpage

To really top it off, lets add a manual (manpage) to really make it comfortable. (Note: you could add 'pod2man' to the requirements-list mentioned above) Also note the extended maincode on the bottom (before the manual).

  if [ "$1" != "--manual" ]; then return 0; fi
  local tempfile="/tmp/foo.1"
  hash pod2man 2>&-
  if [ $? == 1 ]; then echo "please install perl"; exit; fi
  SCRIPT=`readlink -f $0`
  echo "(please wait..)"
  pod2man $SCRIPT > "$tempfile"
  if [ -f "$tempfile" ]; then man "$tempfile"; rm "$tempfile"; fi
  exit 0
manual "$1" && test $# -lt 2 && checkrequirements && usage && exit 65
exit 0
=head1 NAME
   foo - a great cmdline utility
   This utility demystifies the wonderfull world of ...
It does x and y..
=head1 SEE ALSO
L<foo>, L<bar>
=head1 LICENSE
BSD License (so everybody can enjoy it)
=head1 AUTHOR
B<Y>our name


Shellscript rocks, is available on every *NIX system, and it will never die. I hereby take back all insults I did in the past about this language ;) An example of all methods mentioned above:


comments powered by Disqus

All rights reserved by Leon van Kammen under this license