Score:-1

Get output from Bash in Java?

cg flag

I have this this Java code that works:

public class GetNumberOfFiles {
    protected long GetNumberOfFilesMethod(String folder){
        try {
            Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "cd " + folder + "&& find . -type f | grep :*.txt "});
            BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            return stdInput.lines().count();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
}

I created also this code with similar logic, but after a few tries I put the bash code into a separate file.

The Java code:

protected String CheckUserMethod(String user){
        try {

            Process p = Runtime.getRuntime().exec(new String[]{"bash", "-c", "~/Final-Year/src/query", "&& ./checkuser.sh", user});
            BufferedReader srdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
            String a = null;
            while ((a = srdInput.readLine()) != null)
            {
                System.out.println(a);
            }

            return a;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

The bash code is:

#!/bin/bash

# shellcheck disable=SC2237
if ! [ -z "$1" ]
then
  echo "$1"
  cd ~/Final-Year/maps/ && find "$1" -maxdepth 0 -type d -printf 1
fi

The code is working perfectly when I am executing from terminal as it is in this example:

enter image description here

The problem is,when I am executing the code from Java is not even executing the bash file. Do you have any suggestion?

Score:2
hr flag

When you use bash -c, the first argument after the -c is treated as a command, and any additional arguments are passed as positional parameters.

In your first fragment,

{"bash", "-c", "cd " + folder + "&& find . -type f | grep :*.txt "}

you are passing a single concatenated string argument "cd " + folder + "&& find . -type f | grep :*.txt " whereas in the second fragment,

{"bash", "-c", "~/Final-Year/src/query", "&& ./checkuser.sh", user}

you are passing 3 arguments:

  • ~/Final-Year/src/query (which presumably should have been cd ~/Final-Year/src/query
  • && ./checkuser.sh
  • user

so it's equivalent to

bash -c '~/Final-Year/src/query' '&& ./checkuser.sh' user

which executes bash -c '~/Final-Year/src/query' or (corrected) bash -c 'cd ~/Final-Year/src/query' with literal string && ./checkuser.sh as positional parameter $0 and the substituted Java variable user as positional parameter $1

What you likely want is

bash -c 'cd ~/Final-Year/src/query && ./checkuser.sh user'

which would instead be

{"bash", "-c", "cd ~/Final-Year/src/query && ./checkuser.sh " + user}

Alternatively, you could make use of the positional parameter array like

{"bash", "-c", "cd ~/Final-Year/src/query && ./checkuser.sh \"$1\"", "bash", user}

where the shell's name bash is passed as $0 (you could use any arbitrary string here) and Java variable user as $1.

ilie alexandru avatar
cg flag
Apologies for the late response. Thank you so much for your help!
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.