Tcl unknown Command
last modified October 20, 2026
The Tcl unknown command is invoked when the interpreter encounters
an undefined command. It provides a mechanism to handle unknown commands.
Basic Definition
The unknown command is a procedure that Tcl calls for undefined
commands. The default version, defined in Tcl's init.tcl, first
tries to autoload the command (see auto_load) and, in an
interactive shell, to run it as an external program. If that fails, it raises an
"invalid command name" error. The procedure can be redefined to implement
custom behavior.
Syntax: unknown cmdName ?arg arg ...?. The command receives the
unknown command name and its arguments. It must return a valid Tcl result.
Default Unknown Behavior
This example shows the default behavior when an unknown command is called.
# This will trigger the unknown command nonexistent_command
Running this script produces an error because the command doesn't exist and
the default unknown handler, after finding nothing to autoload,
reports the error. This demonstrates Tcl's default behavior.
Custom Unknown Handler
We can override the unknown command to implement custom behavior.
proc unknown {args} {
puts "Unknown command: [lindex $args 0]"
puts "Arguments: [lrange $args 1 end]"
return ""
}
# Test the custom handler
test_command arg1 arg2
This defines a custom unknown handler that prints information about
the unknown command and its arguments. The handler prevents the normal error,
and its return value becomes the result of the missing command. Note that a
replacement handler also disables the default autoloading, so library
procedures such as parray would no longer be found.
Command Auto-loading
The unknown command can be used to implement command auto-loading.
set fd [open greet.tcl w]
puts $fd {proc greet {name} {puts "Hello, $name!"}}
close $fd
proc unknown {cmd args} {
if {[file exists "$cmd.tcl"]} {
source "$cmd.tcl"
return [eval $cmd $args]
}
error "unknown command: $cmd"
}
# This will load greet.tcl and execute greet
greet "John"
file delete greet.tcl
The script first creates the file greet.tcl. The handler checks if a file named
after the command exists. If found, it loads
the file and executes the command. This is a simplified version of what the
default handler does through auto_load and tclIndex
files.
Command Aliasing
The unknown command can be used to create command aliases.
proc unknown {cmd args} {
set aliases {
hi say_hello
bye say_goodbye
}
foreach {alias target} $aliases {
if {$cmd eq $alias} {
return [eval $target $args]
}
}
error "unknown command: $cmd"
}
proc say_hello {} { puts "Hello!" }
proc say_goodbye {} { puts "Goodbye!" }
hi
bye
This implements command aliasing through the unknown handler. When
hi or bye are called, they're translated to their
target commands. This shows how to create command synonyms.
Command Suggestions
The unknown command can suggest similar commands when a command is
not found.
proc unknown {cmd args} {
set commands [info commands]
set matches [lsearch -all -inline -glob $commands "*${cmd}*"]
if {[llength $matches] > 0} {
puts "Unknown command: $cmd"
puts "Did you mean: [join $matches ", "]?"
} else {
puts "Unknown command: $cmd"
}
return ""
}
# Test with an incomplete command name
put "Hello"
This handler suggests similar commands when an unknown command is called. It
searches existing commands for names that contain the unknown name, so the
incomplete name put finds puts. A real misspelling
such as puuts would find nothing with this simple test; that needs a
string-distance measure. This provides a more friendly experience.
Dynamic Command Creation
The unknown command can dynamically create new commands when they're
first called.
proc unknown {cmd args} {
if {[string match "print_*" $cmd]} {
set text [string range $cmd 6 end]
proc $cmd {} "puts \"$text\""
return [$cmd]
}
error "unknown command: $cmd"
}
# This will dynamically create print_hello
print_hello
This handler creates commands on demand when they follow a specific pattern.
Here, commands starting with print_ are created automatically.
The command's behavior is determined by its name. The text is inserted into
the body of the new procedure without quoting, so a name containing quotes or
brackets would be a problem; this is acceptable only in a controlled example.
Best Practices
- Fallback: Rename the original handler (
rename unknown _unknown) and call it for commands your handler does not know, so autoloading keeps working. - Performance: The handler runs for every missing command, so keep it quick.
- Security: Do not build command bodies or file names from unchecked command names.
- Errors: Raise an error for commands you do not handle, instead of silently returning an empty string.
- Scope: The handler is global to the interpreter; limit changes to a slave interpreter if other code depends on the default.
This tutorial covered the Tcl unknown command with practical
examples showing its usage in different scenarios.
Author
List all Tcl Tutorials.