views:

47

answers:

1

Hi all,

I'm writing (under linux or windows+cygwin) a java program that needs to run a command (process P1) and read its stdout (which is mostly binary data useful to my program). This is easy to do, and already done.

The problem is that P1 also prints some status informations on stderr, and I would like to spawn a terminal (like xterm) to show it in a user-readable way. Is there any easy method to do so?

I considered the option of just feeding some JTextArea with the output of stderr, but this program makes use of special control characters (in particular erase last line). Unfortunately, I couldn't find any "Terminal (J)Component" freely available.

So the easiest way would be to be able to open an xterm (P2) that shows everything that comes to its stdin in its window, and start a java thread doing in loop err.read(P1) -> in.write(P2) to transfert everything from stderr(P1) to stdin(P2).
Another option would be to be able to launch something like "xterm -e P1_command" and still be able to capture P1 stdout...

Thank you very much for your help!

PS : I would like to remain as much portable as possible, so I'm not sure going into /dev/pts is a good idea

+2  A: 

Without completely understanding your problem, the easiest solution I can come up with is this (bash will replace $$ with the current process ID making it semi-unique). I also have no idea if this works in cygwin.

mkfifo /tmp/myoutput.$$
trap "rm /tmp/myoutput.$$" EXIT

xterm -e cat /tmp/myoutput.$$ &

runProgram 2>/tmp/myoutput.$$

This will dump stderr to a fifo, which is read by cat in your xterm.

Note that the cat will exit whenever you close the fifo, so if you're spawning multiple instances of your process, then you'll need some other control mechanism, and then there are probably other ways to solve it which are simpler. Such as running the entire thing in an xterm to begin with (including your java program), but I guess that's not possible for some reason or you would've tried it already.

EDIT:
I suppose the most common way is to dump information to a log file, and tail it, like so:

touch /tmp/myprogram.log
xterm -e tail -f /tmp/myprogram.log &
runProgram 2>/tmp/myprogram.log

This should always work, but you might lose log messages if tail starts up too slow (look for flags in tail to echo the entire file before tailing). Combine it with a trap (and 'unique' filename) to remove the file and you don't need to worry about clean up.

What's the reason for not running the entire app in an xterm?

roe
I found the option of mkfifo but, as you said it's probably not the "simpler" (nicer? :-) ) way... (Still, I like your idea of the trap!)Furthermore, although mkfifo exists in cygwin, is it guaranteed to work in a "portable" way?...
Goulou
Can't you just run your entire app in the xterm?
roe
"xterm -e tail " : that seems a good idea (surprised I didn't think about it...). I don't know for sure how it will work with windows+cygwin, but it's at least a good start.
Goulou
>"What's the reason for not running the entire app in an xterm?" : That's simple : the main app is already running, and it starts a process. This process reads some data from a USB probe, sends it (binary) through stdout for the main app, and prints status (connection status, probe's buffer status, bytes read/s...) to stderr so that the user can also follow what's happenning (in particular a buffer overflow that we often have to deal with...)
Goulou