tcltclsh

How do I perform a command substitution in tclsh?


I want to capture the stdout of a command in a variable, similarly to command substitution in Bash:

#!/bin/bash
x="$(date)"
echo $x

I tried doing the same in tclsh but it doesn't do what I want:

#!/bin/tclsh
set x [date]
echo $x

If I execute the script withtclsh myscript.tclsh it gives an error:

invalid command name "date"
    while executing
"date "
    invoked from within
"set x [ date ]"

On the other hand, if I open a TCL interactive shell with tclsh, it does not give an error and the echo line prints an empty string.

Why is my program giving different results when I execute the script with or without the REPL? And it there a way to capture the output of a shell command and store it in a variable, similarly to command substitution in Bash?


Solution

  • When not using Tcl interactively, you need to explicitly use the exec command to run a subprocess.

    set x [exec date]
    # Tcl uses puts instead of echo
    puts $x
    

    In interactive use, the unknown command handler guesses that that's what you wanted. In some cases. Be explicit in your scripts, please!


    You should probably replace running a date subprocess with the appropriate calls to the built-in clock command:

    # Get the timestamp in seconds-from-the-epoch
    set now [clock seconds]
    # Convert it to human-readable form
    set x [clock format $now -format "%a %d %b %Y %H:%M:%S %Z"]
    

    (That almost exactly matches the output of date on this system. The spacing isn't quite the same, but that doesn't matter for a lot of uses.)