This page serve as an anchor to lead people to the most frequent way to detect availability of executables: auto_execok
There actually is a reason to prefer detecting executables using exec instead of auto_execok, that's when the executable returned by auto_execok actually is not executable. This is almost certainly a bug of the execution environment, but at least it bugs Cygwin, thus someone might want to use the following workaround.
Cygwin have a hybrid mix of win32 tcl/tk and their POSIX environment. Let's say we detect availability of cdrecord, auto_execok would return a path which is a symlink, but tcl/tk script running on cygwin's win32 tcl engine cannot invoke symlinks, thus script fail when invoked.
A workaround is to actually run the target executable to do a simple thing, like printing its version number. The code is a bit complicated because you need to worry if version number is written on stderr, resulting failed exec. Thus a second check at $::errorCode is necessary:
if {![catch {exec cdrecord -version}] || [lindex $::errorCode 0] eq "NONE"} { puts stderr "'cdrecord' is available" }