Many issues here. Hopefully these notes will help you figure out what to do.
It seems a bit over-complicated to run things through cmd.exe
just to make echo
piped into plink.exe
work. I'd write that like this:
catch { exec plink.exe -ssh server -pw lucas << "command" } res
Note that like this, we don't need to use eval
at all.
Failing that, if that command is something coming from the user and you need to support command shell syntax with it, you can do this:
set myCommand "echo command | plink.exe -ssh server -pw lucas"
catch { exec cmd.exe /C $myCommand } res
Otherwise you get into the mess of stuff related to the parsing of options to cmd.exe
and that's probably not what you want! (That /C
is important; it tells cmd.exe
“here comes a command”.)
Note that we're still avoiding eval
here. That eval
is (almost) certainly a bad idea with what you're trying to do.
When working with wrapped code, the problem is a different one. The issue there is that Windows processes each use a particular subsystem (it's effectively a compilation option when building the executable if I remember right) and the wrapped wish.exe
and cmd.exe
use different subsystems. Going across the subsystem boundaries is very messy, as the OS tries to be helpful and does things like allocating a terminal for you. Which you didn't want. (I don't remember if you have the problem with direct use of plink.exe
, and I can't check from here due to being on entirely the wrong platform and not having a convenient VM set up.)
To run the plink.exe
in the background, assemble the pipeline like this:
set myCmd [list plink.exe -ssh server -pw lucas]
set chan [open |$myCmd a+]; # r+ or w+ would work just as well for read/write pipe
fconfigure $chan -buffering none -blocking 0
puts $chan "command"
Also, be aware that when using fileevent
you need to take care to detect an EOF condition and close the pipe when that happens:
proc receive {} {
global chan
log [read $chan]
if {[eof $chan]} {
close $chan
}
}
Otherwise when the pipe is closed you'll get an infinite sequence of events on the pipe channel (and the read
will always produce a zero-length result since there's provably nothing there).