Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #31814 > unrolled thread

Getting results of command execution

Started byFredK <fred.l.kleinschmidt@gmail.com>
First post2015-06-17 13:56 -0700
Last post2015-07-03 23:41 -0400
Articles 18 — 4 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Getting results of command execution FredK <fred.l.kleinschmidt@gmail.com> - 2015-06-17 13:56 -0700
    Re: Getting results of command execution Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-17 17:14 -0400
      Re: Getting results of command execution FredK <fred.l.kleinschmidt@gmail.com> - 2015-06-17 14:57 -0700
        Re: Getting results of command execution Martin Gregorie <martin@address-in-sig.invalid> - 2015-06-17 23:07 +0000
        Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-17 21:26 -0400
          Re: Getting results of command execution FredK <fred.l.kleinschmidt@gmail.com> - 2015-06-18 07:18 -0700
          Re: Getting results of command execution FredK <fred.l.kleinschmidt@gmail.com> - 2015-06-18 07:30 -0700
            Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-18 17:37 -0400
              Re: Getting results of command execution FredK <fred.l.kleinschmidt@gmail.com> - 2015-06-19 07:50 -0700
                Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-19 21:33 -0400
                  Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-19 21:56 -0400
                    Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-19 23:02 -0400
                    Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-20 11:11 -0400
                      Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-20 12:14 -0400
                      Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-06-20 20:58 -0400
            Re: Getting results of command execution Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-19 11:01 -0400
        Re: Getting results of command execution Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-18 08:38 -0400
    Re: Getting results of command execution Jeff Higgins <jeff@invalid.invalid> - 2015-07-03 23:41 -0400

#31814 — Getting results of command execution

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2015-06-17 13:56 -0700
SubjectGetting results of command execution
Message-ID<c3df45f4-0172-4986-95e4-cbfb6222610f@googlegroups.com>
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:
            BufferedReader stdInput = new BufferedReader(new
                 InputStreamReader(p.getInputStream()));
 
            BufferedReader stdError = new BufferedReader(new
                 InputStreamReader(p.getErrorStream()));
 
            // read the output from the command
            System.out.println("Here is the standard output of the command:\n");
            while ((s = stdInput.readLine()) != null) {
                System.out.println(s);
            }
             
            // read any errors from the attempted command
            System.out.println(
               "Here is the standard error of the command (if any):\n");
            while ((s = stdError.readLine()) != null) {
                System.out.println(s);
            }

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. I guess I could use:
    "commandA >myfileA 2>&1 ;  commandB >myfileB 2>&1 ; cat myfileA myfileB"

but that seems excessive (and I also need to delete the files, plus I might not even have permission to create files in the current directory)
-- 
Fred K

[toc] | [next] | [standalone]


#31815

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-17 17:14 -0400
Message-ID<mlsnte$efd$1@dont-email.me>
In reply to#31814
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.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31816

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2015-06-17 14:57 -0700
Message-ID<7a28b01f-2a86-4703-98e7-79a7be418abf@googlegroups.com>
In reply to#31815
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 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.
-- 
Fred K

[toc] | [prev] | [next] | [standalone]


#31817

FromMartin Gregorie <martin@address-in-sig.invalid>
Date2015-06-17 23:07 +0000
Message-ID<mlsuja$9rv$1@dont-email.me>
In reply to#31816
On Wed, 17 Jun 2015 14:57:04 -0700, FredK wrote:

> I'm not sure I can accomplish what I want; 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.
>
You can run a shell script containing the commands (Unix/Linux 
terminology) and I'm certain Windows and and OSX have a similar 
capability.


-- 
martin@   | Martin Gregorie
gregorie. | Essex, UK
org       |

[toc] | [prev] | [next] | [standalone]


#31818

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-17 21:26 -0400
Message-ID<mlt6pr$3cc$1@dont-email.me>
In reply to#31816
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?

<http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>

> 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.
>

[toc] | [prev] | [next] | [standalone]


#31824

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2015-06-18 07:18 -0700
Message-ID<a6622ed1-2772-4f91-8a3a-03969f64a2c7@googlegroups.com>
In reply to#31818
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?
> 
> <http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>
> 
> > 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.
> >

[toc] | [prev] | [next] | [standalone]


#31825

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2015-06-18 07:30 -0700
Message-ID<7e0fd613-2e77-44bb-9c7e-7f31dfb33273@googlegroups.com>
In reply to#31818
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?
> 
> <http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>
> 
> > 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 "<Ctrl>+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.
-- 
Fred K

[toc] | [prev] | [next] | [standalone]


#31826

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-18 17:37 -0400
Message-ID<mlvdp7$2ht$1@dont-email.me>
In reply to#31825
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?
>>
>> <http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>
>>
>>> 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 "<Ctrl>+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.


[toc] | [prev] | [next] | [standalone]


#31828

FromFredK <fred.l.kleinschmidt@gmail.com>
Date2015-06-19 07:50 -0700
Message-ID<6122c63f-1e03-4a2e-87eb-2c246352c4fe@googlegroups.com>
In reply to#31826
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?
> >>
> >> <http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>
> >>
> >>> 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 "<Ctrl>+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.
-- 
Fred K

[toc] | [prev] | [next] | [standalone]


#31831

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-19 21:33 -0400
Message-ID<mm2fug$71o$1@dont-email.me>
In reply to#31828
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?
>>>>
>>>> <http://labs.neohapsis.com/2008/04/17/connect-back-shell-literally/>
>>>>
>>>>> 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 "<Ctrl>+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.
<http://www.linusakesson.net/programming/tty/>
Well, what the heck. Why?

[toc] | [prev] | [next] | [standalone]


#31832

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-19 21:56 -0400
Message-ID<mm2han$1ap$1@dont-email.me>
In reply to#31831
On 06/19/2015 09:33 PM, Jeff Higgins wrote:

> Well, what the heck. Why?
<http://www.linusakesson.net/programming/pipelogic/index.php>

[toc] | [prev] | [next] | [standalone]


#31833

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-19 23:02 -0400
Message-ID<mm2l5e$im5$1@dont-email.me>
In reply to#31832
Not to mention this one.
<http://www.linusakesson.net/programming/vimsuspend/index.php>

[toc] | [prev] | [next] | [standalone]


#31835

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-20 11:11 -0400
Message-ID<mm3vtq$kiv$1@dont-email.me>
In reply to#31832
On 06/19/2015 09:56 PM, Jeff Higgins wrote:
> On 06/19/2015 09:33 PM, Jeff Higgins wrote:
>
>> Well, what the heck. Why?
> <http://www.linusakesson.net/programming/pipelogic/index.php>
>
>
Well, it's not Java, but as a personal memento:
GASH - The Good Auld Shell
<http://rust-class.org/pages/ps2.html>

<http://rust-class.org/0/pages/using-rust-for-an-undergraduate-os-course.html>
<http://tldp.org/HOWTO/Text-Terminal-HOWTO.html>

[toc] | [prev] | [next] | [standalone]


#31836

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-20 12:14 -0400
Message-ID<mm43k4$3de$1@dont-email.me>
In reply to#31835
On 06/20/2015 11:11 AM, Jeff Higgins wrote:
> On 06/19/2015 09:56 PM, Jeff Higgins wrote:
>> On 06/19/2015 09:33 PM, Jeff Higgins wrote:
>>
>>> Well, what the heck. Why?
>> <http://www.linusakesson.net/programming/pipelogic/index.php>
>>
>>
> Well, it's not Java, but as a personal memento:
> GASH - The Good Auld Shell
> <http://rust-class.org/pages/ps2.html>
>
> <http://rust-class.org/0/pages/using-rust-for-an-undergraduate-os-course.html>
>
> <http://tldp.org/HOWTO/Text-Terminal-HOWTO.html>
>
<https://github.com/drrb/java-rust-example>

[toc] | [prev] | [next] | [standalone]


#31837

FromJeff Higgins <jeff@invalid.invalid>
Date2015-06-20 20:58 -0400
Message-ID<mm52a1$gg4$1@dont-email.me>
In reply to#31835
On 06/20/2015 11:11 AM, Jeff Higgins wrote:

> Well, it's not Java, but as a personal memento:
Xinu Is Not Unix
<http://www.xinu.cs.purdue.edu/>
RCU - read-copy-update
<http://www2.rdrop.com/users/paulmck/RCU/>

[toc] | [prev] | [next] | [standalone]


#31829

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-19 11:01 -0400
Message-ID<mm1ap2$vt7$1@dont-email.me>
In reply to#31825
On 6/18/2015 10:30 AM, FredK wrote:
>
> 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 "<Ctrl>+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.

     Quick and (very) dirty, Windows version:


import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Foo extends JPanel {

    private final JTextArea screen;
    private final Process shellProcess;
    private final Writer shellInput;
    private final Reader shellOutput;

    private Foo() throws IOException {
       assert SwingUtilities.isEventDispatchThread();
       screen = new JTextArea(24, 80);
       add(new JScrollPane(screen));

       ProcessBuilder builder = new ProcessBuilder();
       builder.command("cmd");
       builder.redirectErrorStream(true);
       shellProcess = builder.start();
       shellInput = new OutputStreamWriter(shellProcess.getOutputStream());
       shellOutput = new InputStreamReader(shellProcess.getInputStream());

       Runnable listener = () -> {
          char[] buffer = new char[512];
          int len;
          do {
             String text;
             try {
                len = shellOutput.read(buffer);
                text = (len >= 0) ? new String(buffer, 0, len) : "*** 
EOF ***";
             } catch (IOException ex) {
                len = -1;
                text = "*** " + ex.getLocalizedMessage() + " ***";
             }

             final String finalText = text;
             SwingUtilities.invokeLater(() -> {
                screen.append(finalText);
             });
          } while (len >= 0);
       };
       new Thread(listener).start();
    }

    public void stopProcess() {
       shellProcess.destroyForcibly();
    }

    private static final String NEWLINE = 
System.getProperty("line.separator");

    public void sendCommand(String command) {
       if (!command.endsWith(NEWLINE)) {
          command += NEWLINE;
       }
       try {
          shellInput.write(command);
          shellInput.flush();
       } catch (IOException ex) {
          Logger.getLogger(Foo.class.getName()).log(Level.SEVERE, null, ex);
          System.exit(1);
       }
    }

    public static void main(String[] unused) {
       SwingUtilities.invokeLater(() -> {
          JFrame frame = new JFrame("Foo");

          final Foo foo;
          try {
             foo = new Foo();
          } catch (IOException ex) {
             Logger.getLogger(Foo.class.getName()).log(Level.SEVERE, 
null, ex);
             System.exit(1);
             return;  // to placate the compiler
          }
          frame.add(foo, BorderLayout.CENTER);

          final JTextField command = new JTextField(60);
          command.addActionListener((ActionEvent e) -> {
             foo.sendCommand(command.getText());
          });
          JLabel label = new JLabel("Command me:");
          label.setLabelFor(command);
          JPanel controls = new JPanel();
          controls.add(label);
          controls.add(command);
          frame.add(controls, BorderLayout.SOUTH);

          frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
          frame.addWindowListener(new WindowAdapter() {
             @Override
             public void windowClosing(WindowEvent e) {
                foo.stopProcess();
                System.exit(0);
             }
          });

          frame.pack();
          frame.setVisible(true);
       });
    }
}

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31822

FromEric Sosman <esosman@comcast-dot-net.invalid>
Date2015-06-18 08:38 -0400
Message-ID<mlue17$v8u$1@dont-email.me>
In reply to#31816
On 6/17/2015 5: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 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.

     On Unixoid systems, you do this by executing a shell as the child
process and feeding it the stream of commands you want executed.  I'm
not sure what the Windows idiom is -- maybe execute cmd.exe? -- but it's
likely to be something similar.

     But that's a separate matter from getting "correct" interleaving
of the stdout and stderr streams, which may be buffered independently
(and differently!) in the various sub-commands.  If the commands are
A,B,C I think you can ensure that all of A's output will precede B's,
and all of B's will precede C's, but unless you've got special knowledge
of A,B,C I don't think you can impose any particular ordering of the
stdout and stderr data they generate individually.

-- 
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM

[toc] | [prev] | [next] | [standalone]


#31948

FromJeff Higgins <jeff@invalid.invalid>
Date2015-07-03 23:41 -0400
Message-ID<mn7knt$nka$1@dont-email.me>
In reply to#31814
On 06/17/2015 04:56 PM, FredK wrote:
> I want to execute a set of commands and get the results.
JEP 102: Process API Updates
<http://openjdk.java.net/jeps/102>

jshell - A shell implementation in Java
<https://code.google.com/p/jshell/>

JShell
http://geophile.com/jshell/

JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)
<http://openjdk.java.net/jeps/222>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web