Java ProcessBuilder and bash - java

I am trying to execute a bash script from Java with ProcessBuilder
my code is :
Process createUser = buildProcess(
"/bin/su",
"-c",
"\"/opt/somedir/testdir/current/bin/psql",
"--command",
commandForUserCreation,
/* "'select * from users'", */
"--dbname",
"mydbname\"",
"myuser"
);
The problem is that I receive error:
/bin/su: unrecognized option '--dbname'
If I put echo in first place of my commands it prints correct command in bash and if I copy/paste this command it works!
Please, help me to resolve this issue.

You need to supply the whole command to execute by su as a single argument. Try this:
Process createUser = buildProcess(
"/bin/su",
"-c",
"/opt/vmware/vpostgres/current/bin/psql --command " + commandForUserCreation + " --dbname mydbname",
myuser
);

This is what I use in processBuilder:
String[] command = new String[] {"echo", "Hello"};
String workspace = "/bin/su";
System.out.println("Trying to run command: "+ Arrays.toString(command));
ProcessBuilder probuilder = new ProcessBuilder(command);
probuilder.directory(new File(workspace));
Process process = probuilder.start();
InputStream is = process.getInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line;
System.out.printf("Output of running %s is:\n",Arrays.toString(command));
while ((line = br.readLine()) != null) {
System.out.println(line);
}
I hope it helps.

Related

Java Execute an external program and capture the output

So i try to Execute an external program and capture the output.
Currently the part that execute command works fine (using .bat file) and i can see the output on the cmd window.
The part that need to read the output not and it seemt that it stack inside my while
This is what i have try:
String[] command = {"cmd.exe", "/C", "Start", "d:\\batFile.bat"};
Process process = Runtime.getRuntime().exec(command);
InputStream is = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
Update
This is my .bat file:
docker volume create --name=mydb
timeout 3
docker run -d -p 27017:27017 -v mydb:/data/db mongo
timeout 3
Maybe you can try to redirect the output like this :
Process runtimeProcess1;
ProcessBuilder pb = new ProcessBuilder("cmd.exe", "/C","Start","d:\\batFile.bat");
pb.redirectOutput(Redirect.INHERIT);
pb.redirectError(Redirect.INHERIT);
pb.redirectInput(Redirect.INHERIT);
runtimeProcess1 = pb.start();
int processComplete1 = runtimeProcess1.waitFor();

Using Runtime.getRuntime().exec with multiple parameters

So I trying to use Runtime.getRuntime().exec to execute a openview command from Java code. This exact command runs fine on command prompt on the server does the necessary updates, but fails to perform when executed through Java code. The issue is that it returns exit status code of success i,e "0" when invoked through Java, but doesn't performs the updates it is suppose to do (appears like it is not executing).
Here is the command :
opcmsg application='Tester Down 11' object='My Support' severity=minor msg_grp='MyGroup' msg_text='DEV: -m=New Details:Request Detail description'
Here is the code :
String[] command = {
"opcmsg",
"application=\'Tester Down 11\'",
"object=\'My Support\'",
"severity=minor",
"msg_grp=\'MyGroup\'",
"msg_text=\'DEV: -m=New Details:Request Detail description\'"
}
p = Runtime.getRuntime().exec(command);
InputStream stderr = p.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String errorDescription = null;
while ( (errorDescription = br.readLine()) != null)
LOGGER.info(errorDescription);
exitStatus = p.waitFor();
LOGGER.info("exitStatus : " + exitStatus);
This worked :
String[] command = { "/bin/sh",
"-c",
"opcmsg application=\'Tester Down 11\' object=\'My Support\' severity=minor msg_grp=\'MyGroup\' msg_text=\'DEV: -m=New Details:Request Detail description\' " }

Start filebeat using a Java code?

I'm using filebeat to read some log files and I need to start filebeat using a Java program. And the filebeat commands are executed using the Windows PowerShell. I used the following code but it didn't work.
try {
ProcessBuilder b1 = new ProcessBuilder("powershell.exe", "/c", "cd \"C:\\Program Files\\Filebeat\" && ./filebeat -e -c filebeat.yml -d \"publish\"\\");
b1.redirectErrorStream(true);
Process p1 = b1.start();
BufferedReader r1 = new BufferedReader(new InputStreamReader(p1.getInputStream()));
String line1;
while (true) {
line1 = r1.readLine();
if (line1 == null) { break; }
System.out.println(line1);
}
} catch(Exception e) {
}
The below code worked.
ProcessBuilder pb = new ProcessBuilder("C:\\Program Files\\Filebeat\\filebeat.exe", "-c", "C:\\Program Files\\Filebeat\\filebeat.yml", "-e");
pb.redirectErrorStream(true);
Process p = pb.start();
BufferedReader bri = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = bri.readLine()) != null) {
System.out.println(line);
}
p.waitFor();
You're confusing PowerShell with CMD. The latter has a parameter /c, the former doesn't. Also, instead of using cd in the comandline you should simply set the working directory on the ProcessBuilder object, and each token of your commandline should be a separate array element.
Change your code to something like this and it should do what you expect:
ProcessBuilder b1 = new ProcessBuilder("cmd.exe", "/c", "filebeat", "-e", "-c", "filebeat.yml", "-d", "\"publish\"");
b1.directory(new File("C:\\Program Files\\Filebeat"));
b1.redirectErrorStream(true);
Process p1 = b1.start();

How to execute terminal command in specific directory from java

I am trying to execute originate command in specific directory "/usr/local/freeswitch/bin", In bin I have to run executable file fs_cli by ./fs_cli command, In fs_cli I have to execute following command
originate loopback/1234/default &bridge(sofia/internal/1789)
Its working fine from terminal, The same command can be executed from bin
./fs_cli -x "originate loopback/1234/default &bridge(sofia/internal/1789)"
I tried folowing java program to do the above task
Process pr = Runtime.getRuntime().exec("./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)\"");
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
I have creted symbolic link of fs_cli and placed in current location
The above program is showing following output
Output
-ERR "originate Command not found!
As far as I am concerned whwn above command is working fine with terminal it should be the same from java, So it shows I am wrong somewhere
Please help me to sort out this problem.
Use ProcessBuilder and supply a directory path
ProcessBuilder pb = new ProcessBuilder(
"./fs_cli",
"-x",
"originate loopback/1234/default &bridge(sofia/internal/1789#192.168.0.198)");
pb.directory(new File("..."));
Process pr = pb.start();
BufferedReader br = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String str = null;
while ((str = br.readLine()) != null) {
System.out.println(str);
}
Where possible, you should provide the command arguments as separate Strings, this will pass each as a separate argument to the process and take care of those arguments that need to be escaped by quotes for you (unless it's expecting the quotes, then you should include them anyway)
The other way is:
ProcessBuilder processBuilder = new ProcessBuilder( "/bin/bash", "-c", "cd /usr/local/freeswitch/bin && ./fs_cli -x \"originate loopback/1234/default &bridge(sofia/internal/1789)\"" );
processBuilder.start();

How to run unix enq command in java program

Here is the unix command for adding a file to the queue.
enq -P QueueName:PrinterName FileName
Is it possible to run the above command using java.
Yes, it's possible using ProcessBuilder:
ProcessBuilder builder =
new ProcessBuilder("enq", "-P", "QueueName", "FileName");
Process process = builder.start();
InputStreamReader streamReader = new InputStreamReader(process.getInputStream());
BufferedReader reader = new BufferedReader(streamReader);
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
See: enq syntax
Process p = Runtime.getRuntime().exec(new String[]{"enq", "-P", "QueueName:PrinterName FileName"});

Categories