Ken
Ken

Reputation: 173

What does this certain piece do in this snippet of TCL code

I`m curious as to what this "2>@ stderr <@ stdin" does in this snippet of code in TCL:

if {[catch {eval exec $listCmds 2>@ stderr <@ stdin } cmdList] } { …

Based on what I know, catch runs the command in the inner curly braces {} and it stores the output in cmdList. If it was successful, it doesn't enter the if statement, and if not then it does. PS: I'm coming from a C++ background.

Upvotes: 2

Views: 187

Answers (2)

glenn jackman
glenn jackman

Reputation: 247202

And the missing piece to Colin's answer is the mix of catch/exec/redirect stderr: only the spawned process's stdout will be captured in cmdList.

  • if you do not redirect the process's stderr to Tcl's stderr, then exec considers any stderr output from the process to be an error:

    $ echo '
        set rc [catch {exec sh -c {echo to stdout; echo to stderr >&2}} result]
        puts "rc=$rc result=>$result<"
    ' | tclsh
    rc=1 result=>to stdout
    to stderr<
    
  • when stderr is redirected, exec now doesn't know about the process's stderr, and the catch resultVar will not capture it

    $ echo '
        set rc [catch {exec sh -c {echo to stdout; echo to stderr >&2} 2>@stderr} result]
        puts "rc=$rc result=>$result<"
    ' | tclsh
    to stderr
    rc=0 result=>to stdout<
    

    Note how the "to stderr" shows up by itself. We can now redirect it like any other stderr output:

    $ echo '
        set rc [catch {exec sh -c {echo to stdout; echo to stderr >&2} 2>@stderr} result]
        puts "rc=$rc result=>$result<"
    ' | tclsh 2>/dev/null
    rc=0 result=>to stdout<
    

Upvotes: 2

Colin Macleod
Colin Macleod

Reputation: 4382

eval exec $listCmds runs a separate program with name and arguments taken from the variable listCmds. (Actually a more modern and safer idiom for this would be exec {*}$listCmds).

2>@ stderr redirects standard error output from this program to the standard error channel of the Tcl script, see https://www.tcl.tk/man/tcl/TclCmd/exec.htm#M20 .

<@ stdin redirects the standard input of this program from the standard input channel of the Tcl script, see https://www.tcl.tk/man/tcl/TclCmd/exec.htm#M11 .

Upvotes: 4

Related Questions