LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 06-11-2008, 07:12 PM   #1
sharky
Member
 
Registered: Oct 2002
Posts: 396

Rep: Reputation: 37
return stdout to a textwidget in tcl/tk


I periodically Run a command line program that returns stdout text to the terminal. I would like to exec this program from a tcl/tk script and have the stdout display in a textbox widget.

Although I did this several years ago I don't remember how it was done and now have no idea how.

Any comments, advice or suggestions would be welcome. Hope I'm clear on what I need.

Last edited by sharky; 06-11-2008 at 07:15 PM. Reason: spelling
 
Old 06-12-2008, 01:04 PM   #2
smoked kipper
Member
 
Registered: May 2008
Location: UK
Distribution: Slackware,Slamd64
Posts: 81

Rep: Reputation: 15
You just need to create a pipe and use that as the commands stdout, capture the output and stuff it into the textwidget. See pipe(2). You'll need to close stdout of the child process after you fork, and dup it to the writing end of the pipe before exec'ing. You should close the ends you don't need (i.e. the write end in the parent and the read end in the child). The pipe man page has a brief example.

Alternatively, you could use popen, which does the hard work for you, but works slightly differently (it passes the command line to /bin/sh). So popen is less work setting it up, but pipe gives you more flexbility (e.g. you could use two pipes if you want to capture stderr too).
 
Old 06-12-2008, 08:29 PM   #3
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
Found a solution

It was a lot simpler than I thought.

.txtBox delete 1.0 end
set myvar [exec mycmd]
.txtBox insert 1.0 end $myvar

This is not what I suggested in my original question because this is not necessarily a capture of STDOUT. The tricky part will be capture STDOUT and STDERR if 'mycmd' barfs.
 
Old 06-13-2008, 08:56 AM   #4
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
Quote:
Originally Posted by smoked kipper View Post
You just need to create a pipe and use that as the commands stdout, capture the output and stuff it into the textwidget. See pipe(2). You'll need to close stdout of the child process after you fork, and dup it to the writing end of the pipe before exec'ing. You should close the ends you don't need (i.e. the write end in the parent and the read end in the child). The pipe man page has a brief example.

Alternatively, you could use popen, which does the hard work for you, but works slightly differently (it passes the command line to /bin/sh). So popen is less work setting it up, but pipe gives you more flexbility (e.g. you could use two pipes if you want to capture stderr too).
"create a pipe"? Sorry, that just went right over my head.
 
Old 06-13-2008, 01:58 PM   #5
smoked kipper
Member
 
Registered: May 2008
Location: UK
Distribution: Slackware,Slamd64
Posts: 81

Rep: Reputation: 15
Sorry, went off on a bit of a tangent there, after I opened the thread my brain blocked out the "tcl/tk", I was leaning towards C for some reason. ?

There is also the open command. You can redirect stderr to a file as in the shell, not sure if you can capture it, my tcl is extremely rusty (and was never particularly shiny to begin with...), but you can always read the file afterwards.

Last edited by smoked kipper; 06-13-2008 at 02:03 PM.
 
Old 06-13-2008, 10:20 PM   #6
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
catch is the key

It turned out to be very easy to capture stderr and write it to my text widget.

.txtbox delete 1.0 end
catch {exec $myCmd} result
.txtbox insert 1.0 $result

Anything returned by 'exec $myCmd' gets written to $result.

Now I need to convert $result into an array. That will be another thread.

Regards all,
 
Old 05-08-2009, 08:21 AM   #7
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
Quote:
Originally Posted by sharky View Post
It turned out to be very easy to capture stderr and write it to my text widget.

.txtbox delete 1.0 end
catch {exec $myCmd} result
.txtbox insert 1.0 $result

Anything returned by 'exec $myCmd' gets written to $result.

Now I need to convert $result into an array. That will be another thread.

Regards all,
This actually doesn't work like I thought. I'm doing another tcltk script and this actually doesn't write to the text widget until $myCmd is completed.

I've done some googling and found some hints on how to 'pipe' stdout and stderr to the widget but haven't gotten anything to work.

Any suggestions would be appreciated. I'll post the 'non-working' code I have later today after I get to work.
 
Old 05-08-2009, 01:27 PM   #8
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
This is the code I have so far that does NOT work.

Code:
if [catch {open "| ~/projects/$sel/${sel}.csh"} result] {
    .txtCreateEnv insert end $result
} else {
    fileevent $result readable "Log {$result}"
}

proc Log {result} {
	if [eof $result] {
		catch {close $result}
	} else {
		gets $result line
		.txtCreateEnv insert end $line
		.txtCreateEnv see end
	}
}
sel is defined earlier. The command after the open statement runs because I can see the generated results. However, the text widget is empty.
 
Old 05-08-2009, 02:12 PM   #9
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
Quote:
Originally Posted by sharky View Post
This is the code I have so far that does NOT work.

Code:
if [catch {open "| ~/projects/$sel/${sel}.csh"} result] {
    .txtCreateEnv insert end $result
} else {
    fileevent $result readable "Log {$result}"
}

proc Log {result} {
	if [eof $result] {
		catch {close $result}
	} else {
		gets $result line
		.txtCreateEnv insert end $line
		.txtCreateEnv see end
	}
}
sel is defined earlier. The command after the open statement runs because I can see the generated results. However, the text widget is empty.
I put a statement after the 'gets' statement, "puts $line", and I see the expected output returned to the terminal. I have no idea why it's not getting written to the text widget.
 
Old 05-08-2009, 04:00 PM   #10
sharky
Member
 
Registered: Oct 2002
Posts: 396

Original Poster
Rep: Reputation: 37
Quote:
Originally Posted by sharky View Post
This is the code I have so far that does NOT work.

Code:
if [catch {open "| ~/projects/$sel/${sel}.csh"} result] {
    .txtCreateEnv insert end $result
} else {
    fileevent $result readable "Log {$result}"
}

proc Log {result} {
	if [eof $result] {
		catch {close $result}
	} else {
		gets $result line
		.txtCreateEnv insert end $line
		.txtCreateEnv see end
	}
}
sel is defined earlier. The command after the open statement runs because I can see the generated results. However, the text widget is empty.
It's working now and I didn't change any of the code posted above. Immediately following the first if statement I had ".txtCreateEnv configure -state disabled". After removing that line the stdout and stderr start streaming to the widget. To disable the widget ( I don't want it to be editable ) I added the configure statement after the catch statement in the Log proc.
 
  


Reply

Tags
stdout, tcl


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Stdout SlacUser Linux - General 4 06-28-2007 09:07 AM
Cannot find Tcl dll ( Perl's Tcl bridge ) Xyem Linux - Software 2 08-08-2006 09:45 AM
redirecting stdout to /dev/null and stderr to stdout? Thinking Programming 1 05-18-2006 02:36 AM
what is stdout stefaandk Linux - Newbie 1 09-06-2005 07:20 PM
stdout with tk? sk8guitar Programming 1 07-30-2003 02:48 PM


All times are GMT -5. The time now is 12:59 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration