question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

How o implement the pipe "|"

See original GitHub issue

Hi, I would like to execute some commands with JProc library and meet some problem, after studied the tutorial still can’t get the solution, so ask some help here.

My command is simple with some pipes, for example, the simple command is:

# adb devices
List of devices attached
emulator-5554	device

and then I would like to add one pipe:

#adb devices | tail -n +1
emulator-5554	device

and then finally I would like to add more one pipe:

#adb devices | tail -n +2 | awk '{print $1}'
emulator-5554

so my script is:

ByteArrayOutputStream output = new ByteArrayOutputStream();
        ProcResult result = new ProcBuilder("adb")
                .withArgs("devices")
                .withOutputStream(output).run();
        System.out.println(output.toString());
        new ProcBuilder("tail")
                .withArgs("-n", "+2")
                .withOutputStream(output)
                .run();
        System.out.println(output.toString());
        new ProcBuilder("awk")
                .withArgs("'{print $1}'")
                .withOutputStream(output)
                .run();
        System.out.println(output.toString());

it doesn’t work.

and also

ByteArrayOutputStream output = new ByteArrayOutputStream();
        ProcResult result = new ProcBuilder("adb")
                .withArgs("devices")
                .withOutputConsumer(stream -> new ProcBuilder("tail")
                        .withArgs("-n", "+2")
                        .withOutputConsumer(stream1 -> {
                            new ProcBuilder("awk")
                                    .withArgs("'{print $1}'")
                                    .withOutputStream(output).run();
                        }).run())
                .run();
        System.out.println(output.toString());

it also doesn’t work.

Could you help to provide some solution for my question? Thanks.

Issue Analytics

  • State:open
  • Created 4 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
fleipoldcommented, Mar 21, 2020

Proper pipelining is currently a hassle to implement with JProc. In theory a pair of PipeInputStream and PipeOutputStream can be used to connect the output of one command with the input of another command. There seems to be first a little bug in JProc around not closing the output stream before the writing thread terminates that leads to an exception (this could be fixed). Secondly, there is currently a synchronous interface, which means the user would have to make sure each command is running in (and blocking) its own thread. That is not in the spirit of the library.

So I’ll outline a potential solution here. It would be much nicer to have a declarative interface that takes a couple of process builders and takes care of the spawning connecting and monitoring the processes. To stick with the example given here, something like this:

PipelineResult result = new PipelineBuilder(
    new ProcBuilder("adb").withArgs("devices"),
    new ProcBuilder("tail").withArgs("-n", "+2"),
    new ProcBuilder("awk").withArgs("{print $1}")
)
.withTimeout(10000)
.run();

result.getOutputString()

The PipelineBuilder would take care of overall pipeline input and output, timeout etc. And the PipelineResult would represent the result of the overall pipeline run (n exit codes, rather than 1). PipelineBuilder#run would block until the whole pipeline has completed and then return the result or indicate the appropriate error.

0reactions
fleipoldcommented, Mar 24, 2020

@ansonliao good catch. The withInput() method was inadvertently set to be package private. I fixed it to be public. The new release 2.3.0 has been pushed and is currently percolating through the maven infrastructure.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Implementing pipe in C - linux - Stack Overflow
Implementing pipe in C · 3. creating two pipes is not enough. · related: Connecting n commands with pipes in a shell?. Here's...
Read more >
pipe() System call - GeeksforGeeks
Pipe is one-way communication only i.e we can use a pipe such that One process write to the pipe, and the other process...
Read more >
6.2.2 Creating Pipes in C
To create a simple pipe with C, we make use of the pipe() system call. It takes a single argument, which is an...
Read more >
Understanding Pipes in Unix with a sample implementation
A “Pipe” is created using the “pipe” function. The input to the function is an integer array of size 2. On successful return...
Read more >
How are Unix pipes implemented? - Abhijit Menon-Sen
The pipe system call creates an I/O mechanism called a pipe. The file descriptor returned can be used in both read and write...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found