Version 5 of Playing Bourne shell

Updated 2002-01-31 15:20:48

Richard Suchenwirth will have to exercise Tcl with colleagues who are familiar with the Bourne shell (/bin/sh - see Tcl heritage for the influences it had on Tcl!), and one task will be to prelace /bin/sh scripts with equivalent Tcl scripts.

To make this migration easier, I am planning to introduce some syntactic sugar (Salt and sugar), so familiar built-ins can still be used. Most simply with interp alias:

 interp alias {} echo {} puts stdout
 interp alias {} read {} gets stdin ;# if we don't need the real [read]
 interp alias {} -r   {} file readable
 interp alias {} -w   {} file writable
 interp alias {} -x   {} file executable

Note however that echo's output cannot be redirected to a file, or through a pipe. Things like

 foo=`echo $bar | grep "^grill"`

would have to be restructured:

 set foo [exec grep ^grill <<$bar]

which also has its charms, but needs habituation. (On the other hand, a Tcl'er would prefer regexp anyway...)

Another difference is the exit status - if grep can't find a thing, it still raises no direct error in /bin/sh, but you can check the exit status with the special variable $? afterwards.


The following one-liner emulates a frequently used part of /bin/sh's test command:

 proc -f name {expr {[file exists $name] && [file type $name]=="file"}}

This way, /bin/sh code written like this:

 if [ -f $filename ] ...

needs no rewriting - but be aware that this is not a complete emulation of tests switches, so

 if [ $# -ne 1 ] ...

would have to rewritten in expr syntax (braced condition, C operators), but we even emulate the Perlish special variable ?# :

 set # [llength $argv]
 if {${#} != 1 } ...

Tcl and other languages - Arts and crafts of Tcl-Tk programming