Vahagn
Vahagn

Reputation: 4820

How to call bash commands from tcl script?

Bash commands are available from an interactive tclsh session. E.g. in a tclsh session you can have

% ls

instead of

$ exec ls

However, you cant have a tcl script which calls bash commands directly (i.e. without exec).

How can I make tclsh to recognize bash commands while interpreting tcl script files, just like it does in an interactive session?

I guess there is some tcl package (or something like that), which is being loaded automatically while launching an interactive session to support direct calls of bash commans. How can I load it manually in tcl script files?

Upvotes: 7

Views: 14402

Answers (3)

Donal Fellows
Donal Fellows

Reputation: 137567

If you want to have specific utilities available in your scripts, write bridging procedures:

proc ls args {
    exec {*}[auto_execok ls] {*}$args
}

That will even work (with obvious adaptation) for most shell builtins or on Windows. (To be fair, you usually don't want to use an external ls; the internal glob command usually suffices, sometimes with extra help from some file subcommands.) Some commands need a little more work (e.g., redirecting input so it comes from the terminal, with an extra <@stdin or </dev/tty; that's needed for stty on some platforms) but that works reasonably well.

However, if what you're asking for is to have arbitrary execution of external programs without any extra code to mark that they are external, that's considered to be against the ethos of Tcl. The issue is that it makes the code quite a lot harder to maintain; it's not obvious that you're doing an expensive call-out instead of using something (relatively) cheap that's internal. Putting in the exec in that case isn't that onerous…

Upvotes: 13

SingleNegationElimination
SingleNegationElimination

Reputation: 156138

What's going on here is that the unknown proc is getting invoked when you type a command like ls, because that's not an existing tcl command, and by default, that command will check that if the command was invoked from an interactive session and from the top-level (not indirectly in a proc body) and it's checking to see if the proc name exists somewhere on the path. You can get something like this by writing your own proc unknown.

For a good start on this, examine the output of

info body unknown

Upvotes: 8

Dennis Williamson
Dennis Williamson

Reputation: 359925

One thing you should know is that ls is not a Bash command. It's a standalone utility. The clue for how tclsh runs such utilities is right there in its name - sh means "shell". So it's the rough equivalent to Bash in that Bash is also a shell. Tcl != tclsh so you have to use exec.

Upvotes: 4

Related Questions