Path: csiph.com!usenet.pasdenom.info!nntpfeed.proxad.net!proxad.net!feeder1-2.proxad.net!137.226.75.22.MISMATCH!newsfeed.fsmpi.rwth-aachen.de!newsfeed.straub-nv.de!eternal-september.org!feeder.eternal-september.org!mx02.eternal-september.org!.POSTED!not-for-mail From: Jeff Higgins Newsgroups: comp.lang.java.programmer Subject: Re: Getting results of command execution Date: Fri, 19 Jun 2015 21:33:03 -0400 Organization: A noiseless patient Spider Lines: 96 Message-ID: References: <7a28b01f-2a86-4703-98e7-79a7be418abf@googlegroups.com> <7e0fd613-2e77-44bb-9c7e-7f31dfb33273@googlegroups.com> <6122c63f-1e03-4a2e-87eb-2c246352c4fe@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252; format=flowed Content-Transfer-Encoding: 7bit Injection-Date: Sat, 20 Jun 2015 01:34:08 +0000 (UTC) Injection-Info: mx02.eternal-september.org; posting-host="8e164d158183579609bf09837dee5210"; logging-data="7224"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18/pc/w1K0xYMJUrxb5w257IpHm4OaRV2M=" User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Icedove/31.7.0 In-Reply-To: <6122c63f-1e03-4a2e-87eb-2c246352c4fe@googlegroups.com> Cancel-Lock: sha1:7YqxTTBz2ytQaIoIKwVkNdzM004= Xref: csiph.com comp.lang.java.programmer:31831 On 06/19/2015 10:50 AM, FredK wrote: > On Thursday, June 18, 2015 at 2:40:15 PM UTC-7, Jeff Higgins wrote: >> On 06/18/2015 10:30 AM, FredK wrote: >>> On Wednesday, June 17, 2015 at 6:28:51 PM UTC-7, Jeff Higgins wrote: >>>> On 06/17/2015 05:57 PM, FredK wrote: >>>>> On Wednesday, June 17, 2015 at 2:14:45 PM UTC-7, Eric Sosman wrote: >>>>>> On 6/17/2015 4:56 PM, FredK wrote: >>>>>>> I want to execute a set of commands and get the results. So I start with, >>>>>>> on Unix; >>>>>>> process P = Runtime.getRuntime().exec("commandA; commandB"); >>>>>>> >>>>>>> or on Windows >>>>>>> process P = Runtime.getRuntime().exec("commandA & commandB"); >>>>>>> >>>>>>> How do I get the results of the output AND error output in the order they are created? >>>>>>> >>>>>>> If I use this type of coding: >>>>>>> [...] >>>>>>> I get all of the stdout, followed by all of the stderr. But suppose commandA writes some output, then some errors, then more outputs, etc. I want to retrieve them in that order. >>>>>> >>>>>> You could try using a ProcessBuilder to set up your Process, and >>>>>> use its redirectErrorStream() method to merge stdout and stderr before >>>>>> calling start(). But even then, you'll be at the mercy of whatever >>>>>> buffering takes place in the external process itself: If that process >>>>>> holds on to stdout data until it's got a bufferload, but emits stderr >>>>>> data right away (this is the default behavior for many C programs), >>>>>> the mingled data will be temporally scrambled no matter what you do >>>>>> on the receiving side. >>>>>> >>>>>> >>>>> I'm not sure I can accomplish what I want; >>>> >>>> I'm sure that you're clear on what you want to accomplish >>>> but so far you haven't made it clear to me. It sounds as if >>>> you want to plant a Java process between a user and his CLI >>>> (sh, cmd.exe, ...) or perhaps replace it? >>>> >>>> >>>> >>>>> I haven't been able to find anything that will let me execute multiple commands in the same invocation. >>>>> >>>>> I want to pass along user commands to be executed, and there might be a "cd" imbedded in the string, or setting some environment variables, or any of a multitude of things that cause one command to depend on the results of some previous command(s), so it I can't just execute each command in a separate process. >>>>> >>> >>> The requirement is essentially that I want to include a panel in my program that acts like a shell. So throughout the lifetime of the program, in addition to interacting with the program the user can also use it as if it were a shell - kind of like a Unix xterm, with additional capabilities. For example, the user could type "ls", then point to a file name, right-click on it and it would open up an editor for that file (based on what kind of file it is), or if it is the name of a directory, cd to that directory and possibly execute ls in that directory. Typing "+U" would execute "cd ..;pwd;ls", plus other features. >>> >>> I have written something like this in C using Motif, and it works fine - I just fork at the beginning and the child becomes a shell, and I redirect the pipes such that I have access to the shell's input, output, and error streams. >>> >>> But I don't know how to do this in Java. >>> >> >> Thanks for the explanation. >> That is pretty much what I had imagined you are looking for. >> I'm afraid such a thing is well beyond my skill set and >> I'm impressed that you've got something working albeit in >> another programming environment. >> I wish you good luck and would love to here back about >> your successes. > > Here's what I am now doing: > First, I store the current working directory as currentDir. > Then I create a meta-command from the actual command: > > private final String[] cbufWindows = { "cmd", "/c", "" }; > private final String[] cbufLinux = { "bash", "-c", "" }; > String[] buf; > String command; > if ( platform == Platform.UNIX ) { > command = "cd " + dir + "; " + cmd + "; echo " + END_STR > + "; echo $?; pwd"; > cbufLinux[2] = command; > buf = cbufLinux; > } else if ( platform == Platform.WINDOWS ) { > command = "pushd " + dir + " & " + cmd + " & echo " + END_STR > + " & cd &popd"; > cbufWindows[2] = command; > buf = cbufWindows; > } else { > return; // unimplemented for other platforms > } > > Runtime rt = Runtime.getRuntime(); > Process p = rt.exec(buf); > > Here, Platform is an enum defined by me, and END_STR is a sentinel that is just a constant long string of gibberish unlikely to be input by the user or output by a command; this is to determine when the command actually ends. > > Note that in my meta-command I first cd to the current directory, execute the command, echo the ENDSTR, then echo the (possibly new) current directory. > > When reading the output of the command, I look for the sentinel, then read the echoed directory and store it back in "currentDir". > > This works fine as long as the command does not require interactive user input, but is sufficient for my needs. > I'm kinda tempted to ask why but probably shouldn't. Well, what the heck. Why?