Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash talking to a sub-process of java?

I'm trying to make a bash script that will talk to a java program that waits for my commands via bash. the java program is running as a server with a very limited GUI so I'm working on making a basic UI for it that will add functionality to it, any help on this topic would be nice.

The ways I've tried to start it currently are:

INPUTFD=258
#exec "$INPUTFD"> >(exec java -Xmx512M -Xms512M -jar server.jar)

with commands like

(echo "kick ${user}") >&"$INPUTFD"

and the one I'm using now

java -Xmx512M -Xms512M -jar server.jar & echo "Started"

pid=$!

but I can't find anything on google to help me use echo or something like that to help here

I was thinking a pipe might work but I think I would have to move a big chunk of the script over into another file to use the pipe which then my echo commands in the script don't seem to want to work any more, so, I'm open to any ideas, Thanks vzybilly

EDIT: (second time typing this, sorry if not all of it makes sense now) After google-ing and thinking on the idea more deeply I found a better way to put the question. the Script (now shall be called the main program, or main script) will interact with the user and depending on what the user tells the main program it will tell the java program something that it made something, in some cases it will be the same as the users input in others it will be the main programs own thing made by what the user said to the main program. the main program will be handling two outputs and one input (terminal both ways, and only one way to the java program)

A way that I thought might work is having a file and another script between the main script and the java program the other script would be named something like server_handler.sh (we'll call it handler script) the way it would work is in the main script a command like this to get it going:

server_handler.sh | java -jar server.jar

Then when we want to say something to the server from the main script we do this:

echo "what we want to tell the sever" >> cmd.tmp

With this, all that the handler script is doing is reading from the file and echoing it out through the pipe to the java program, the issue i run into here is how do I make the handler script know what it has read or delete the lines it has read even if the file is being added to while reading? (some commands will be put in up to 27 times in a row, and it will normally take afew minutes of the sever up and running for a command to be usable (trash otherwise) and sometimes there might never be a command in the servers current run, or for days). I can write to a file while talking in the terminal in a script so the main script wouldn't be hard but what would be in the handler script?

FINAL WORKING SCRIPT:

run.sh:

#!/bin/bash
tail -f input.txt | java server.jar &
echo "Do Not Close This Window Or Press Enter Till Server Is Off Line,"
read -p "  Doing So Will Force Close The Server, Please press enter when done."

main script calling:

gnome-terminal -x ./run.sh

Command Issue-ing to server:

echo "command to server" >> input.txt

I have yet to put it through the hard test but it should stay working

like image 580
vzybilly Avatar asked Jan 17 '26 01:01

vzybilly


1 Answers

One way to do it is using combination of perl and shell scripts. But ideal option would be implement the server as Socket server so that you can connect from anywhere. Using netcat command you can even send message to a socket server from shell script.

Here is an example of perl/shell script option. Java app gets input from a file input.txt that can be appended at run time.

EchoServer.java

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class EchoServer {
    public static void main(String[] args) throws IOException {
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        String input = null;
        System.out.println("EchoServer started");
        while((input = reader.readLine()) != null) {
            System.out.println("Input: " + input);

            if("exit".equalsIgnoreCase(input)) {
                System.exit(0);
            }
        }
    }
}

perl wrapper for java app (java-wrapper.pl)

#!/usr/bin/perl -w
use strict;

open DATA, "java EchoServer | tail -f input.txt |"   or die "Couldn't execute program: $!";
while(my $line = <DATA>) {
  chomp($line);
  print "$line\n";
}
close DATA;

example shell program that sends the input for Java app (shell.sh)

for i in 1 2 3 4 5 6;
do
  echo "sending $i" >> input.txt;
  sleep 1;
done

To run:

  1. Create an empty input.txt file (touch input.txt)
  2. Run java-wrapper.pl in one terminal window
  3. Run shell.sh in another terminal window

Output:

$ ./java-wrapper.pl
sending 1
sending 2
sending 3
sending 4
sending 5
sending 6

EDIT: I just realized, you don't need the PERL part. You can just call,

java EchoServer | tail -f input.txt

from main script and append input.txt using echo

$ java EchoServer | tail -f input.txt
sending 1
sending 2
sending 3
sending 4
sending 5
sending 6

EDIT2: As OP mentioned, the correct command should be

tail -f input.txt | java EchoServer

$ tail -f input.txt |java EchoServer
EchoServer started
Input: sending 1
Input: sending 2
Input: sending 3
Input: sending 4
Input: sending 5
Input: sending 5
like image 120
Jeesmon Avatar answered Jan 19 '26 14:01

Jeesmon



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!