I am using this command line argument to clone a database :-
"C:\Program Files\MySQL\MySQL Server 5.6\bin\mysqldump" -u root -ppass -d oldDB | mysql -u root -ppass -DnewDB
This piece works fine when directly pasted into command line. But, when I tried running this argument using java, it did not work. My java code is :-
String serverLoc = "C:\\Program Files\\MySQL\\MySQL Server 5.6\\";
String a = "\"" + serverLoc + "bin\\mysqldump\" " ;
String cmd = a + "-u root -ppass -d oldDB | mysql -u root -ppass -DnewDB";
Process runtimeProcess = Runtime.getRuntime().exec(executeCmd);
int processComplete = runtimeProcess.waitFor();
if (processComplete == 0) {
System.out.println("SUCCESS");
} else {
System.out.println("ERROR");
}
//OUTPUT : ERROR
Exception handling not shown as no stack trace is printed. When I print cmd, the above desired string is printed which works when pasted into command line. Please help me solve this dilemma.
I believe on windows you have to call the command this way:
Runtime.getRuntime().exec("cmd " + ecuteCmd)
Also I think it is better to use Runtime.getRuntime().exec(String[]) method
String prog = "C:\\program files\\server\\xampp\\mysql\\bin\\mysql";
String user = "-uroot";
String pass = "-ppass";
Process runtimeProcess = Runtime.getRuntime().exec(new String[] { prog, user, pass });
The modern way by using ProcessBuilder: thx #Daniel
String prog = "C:\\program files\\server\\xampp\\mysql\\bin\\mysql";
String user = "-uroot";
String pass = "-ppass";
ProcessBuilder builder = new ProcessBuilder(prog, user, pass);
Process runtimeProcess = builder.start();
int result = runtimeProcess.waitFor();
//...
Related
I am trying to run a command to read a string from a file inside a remote address (and I'm sure the file is there), this command works when I run it on the bash but it doesn't work when I run it in my java code.
Runtime rt = Runtime.getRuntime();
String[] command;
String line;
try {
command = new String[] {"sh", "-c", "\"sshpass " + "-p " + password + " ssh " + user + "#" + ip + " 'cat " + file.getAbsolutePath() + "'\"" };
Process mountProcess = rt.exec(command);
mountProcess.waitFor();
bufferedReader = new BufferedReader(new InputStreamReader(mountProcess.getInputStream()));
while ((line = bufferedReader.readLine()) != null) {
user_list.put(user, line);
}
bufferedReader.close();
bufferedReader = new BufferedReader(new InputStreamReader(mountProcess.getErrorStream()));
while ((line = bufferedReader.readLine()) != null) {
LOGGER.debug("Stderr: " + line);
}
bufferedReader.close();
} catch ...
No line is added to my user_list (so the line from getInputStream is null) and I get the following error from the logger in the code:
Stderr: sh: 1: sshpass: not found
If I use the exact same command on the bash it works and it prints the string I need.
sshpass -p password ssh remote#192.168.1.10 'cat /home/ID/ID'
Anyone knows why this is happening? thanks!
I'd suggest you don't need to use sh to wrap your command. Try
command = new String[] {"sshpass", "-p", password, "ssh", user + "#" + ip, "cat " + file.getAbsolutePath() };
If you need to use sh, then remove the escaped double quotes from the command string: you are sending those as literal characters:
command = new String[] {
"sh",
"-c",
String.format("sshpass -p %s ssh %s#%s 'cat %s'", password, user, ip, file.getAbsolutionPath())
};
If you're still getting "command not found", then you need to either specify the full path to sshpass, or ensure that its directory is in your PATH.
When doing this command with java the user is tomcat8 instead of root (when used in the bash terminal)
The solution that worked for me included some flags:
String.format("/usr/local/bin/sshpass -p %s /usr/bin/ssh -q -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no %s#%s 'cat %s'", password, user, ip, file.getAbsolutePath());
I'm trying to get the output of grep linux shell command in java by using process builder. But i got a stuck in this case. Please help me.
Thank in advice!
String[] args = new String[7];
args[0] = "/bin/bash";
args[1] = "-c";
args[2] = "grep";
args[3] = "-n";
args[4] = "-e";
args[5] = "KERNELVERSION";
args[6] = kernelFilePath.trim();
ProcessBuilder pb;
Process process = null;
try {
pb = new ProcessBuilder(args);
pb = pb.directory(new File(directory));
pb.inheritIO();
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
process = pb.start();
process.waitFor();
} catch (IOException | InterruptedException e) {
System.out.println("executeCmdWithOutput() exception : " + e.toString());
} finally {
if (process != null) {
process.destroy();
}
}
==> Error:
Usage: grep [OPTION]... PATTERN [FILE]...
Try 'grep --help' for more information.
I tried the command in bash and it worked fine:
grep -n -e KERNELVERSION ..../Makefile
Have you tried change the args[2] as full command?
Also, you can use pgrep, it does not require you to use pipe.
You don't need to explicitly run /bin/bash in order to execute the grep process. Just call it directly and ProcessBuilder will run it:
String[] args = {"grep", "-n", "KERNELVERSION", kernelFilePath.trim()};
Also, you don't need to use the -e option, unless there are multiple patterns that you are searching for.
If you really wanted to run grep in /bin/bash:
String[] args = {"/bin/bash", "-c", "grep -n KERNELVERSION " + kernelFilePath.trim()};
passes a single argument to bash containing the full command and arguments to execute.
I use java to excute a command line to create a database, i get an error when i excute this piece of code:
private final String POSTGRES_PATH = "\"C:\\Program Files\\PostgreSQL\\9.3\\bin\\psql.exe\"";
private final String DATA_BASE = "bd_name";
private void creerDataBase() {
String command = this.POSTGRES_PATH + " -U postgres -d postgres -c \"CREATE DATABASE " + this.DATA_BASE + "\"";
System.out.println("command = " + command);
String creerBDD = executerCommande(command);
System.out.println("Resultat : " + creerBDD);
}
public String executerCommande(String command) {
String line;
String resultat = "";
try {
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
while (true) {
line = r.readLine();
if (line == null) {
break;
}
resultat += line + "\n";
}
} catch (Exception e) {
System.out.println("Exception = " + e.getMessage());
}
return resultat;
}
I get this result:
command = "C:\Program Files PostgreSQL\9.3\bin\psql.exe"\ -U postgres -d postgres -c "CREATE DATABASE bd_name"
and this error:
'C:\Program' n'est pas reconnu en tant que commande interne
This mean that Program is not an intern command.
but when i excute this command in CMD it work fine?
Is there any way to Build this Path because the ProcessBuilder not recognize C:\Program Files
Thanks for #Aaron his idea helps me so i solved this problem using this:
private final String POSTGRES_PATH = "C:\\PROGRA~1\\PostgreSQL\\9.3\\bin\\psql.exe";
this C:\\PROGRA~1 inteed of this: C:\\Program Files
A possible solution would be to remove the path (with spaces) from your constant field and use the directory method:
Sets this process builder's working directory. Subprocesses subsequently started by this object's start() method will use this as their working directory. The argument may be null -- this means to use the working directory of the current Java process, usually the directory named by the system property user.dir, as the working directory of the child process.
Changing your code to:
private final String POSTGRES_DIR = "C:\\Program Files\\PostgreSQL\\9.3\\bin\\"
private final String POSTGRES_COMMAND = "psql.exe";
....
ProcessBuilder builder = new ProcessBuilder("cmd.exe", "/c", command).directory(new File(POSTGRES_DIR));
.....
Don't run cmd.exe if you want to run a separate binary program.
cmd.exe is for scripts like *.cmd or *.bat
With cmd.exe you have to pass your command as an argument of CMD, and you should manage all OS-specific pitfalls like long paths with whitespaces, quotes inside qoutes etc.
Instead, you had better run psql itself.
The ProcessBuilder takes a command and all the arguments as a list of separate strings. And ProcessBuilder is clever enough to do all the necessary magic with quotes and whitespaces by itself.
And take attention to the list of arguments - shells separate arguments by whitespaces, while psql might recognize the sequence of strings as a single argument.
We may assume that -U postgress is a single argument for psql, but for shell (cmd.exe in our case) these are two separate arguments - -U and postgress, so we should pass them to the ProcessBuilder separately
So the better way to run psql is to run it directly, something like that:
new ProcessBuilder("C:\\Program Files\\PostgreSQL\\9.3\\bin\\psql.exe",
"-U", "postgres",
"-d", "postgres",
"-c", "\"CREATE DATABASE " + this.DATA_BASE + "\"");
What you could try is instead of the space between program and files is %20 or \s.
So like:
command = "C:\\Program%20Files\\PostgreSQL\\9.3\\bin\\psql.exe"
or
command = "C:\\Program\sFiles\\PostgreSQL\\9.3\\bin\\psql.exe"
I hope one of them works for you, please let me know
EDIT: use double \ to get it to recognize the \
I am having a hard time figuring out how to pass command line options through Java.
My Java code needs to call a binary file which in turn runs some instructions.
The command I need to pass is
./program 100 -r 1
Now there is no way can pass the option -r 1.
In my Java code, if I run:
command=new String [2];
command[0] = ".//program";
command[1] = " "+String.valueOf(nScen);
Process p = Runtime.getRuntime().exec(command);
everything works fine, and program is run correctly. nScen is an integer.
However, if I try
command=new String [3];
command[0] = ".//program";
command[1] = " "+String.valueOf(nScen);
command[2] = " -r 1";
Process p = Runtime.getRuntime().exec(command);
or
command=new String [2];
command[0] = ".//program";
command[1] = " "+String.valueOf(nScen)+" -r 1";
Process p = Runtime.getRuntime().exec(command);
program does not run. I tried other things like using .concat instead of + to merge strings.
What is the correct way of doing this?
Thanks for the help.
You could do this:
Process proc = Runtime.getRuntime().exec("./program " + nScen + " -r 1");
int exitVal = proc.waitFor();
You'll also need to catch exceptions.
I have java code which should stop windows service
When i try it on other commands which do not need admin permissions that works great but to stop windows service i have to start command line as administrator
I tried for example code to start notepad just for checking if this cooperation java with command line works great.
String[] start = {"cmd.exe", "/c", "start", "notepad"};
Process runtimeProcess = Runtime.getRuntime().exec(start);
int processComplete = runtimeProcess.waitFor();
but if i try command to run command line as administrator that failed:
String[] startAsAdmin= new String [] {
"CMD.EXE",
"/C",
"RUNAS /profile /user:"
+ "administrator"
+ " ", "start", "notepad"};
Process runtimeProcess = Runtime.getRuntime().exec(startAsAdmin);
runtimeProcess.waitFor();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(runtimeProcess.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(runtimeProcess.getErrorStream()));
BufferedWriter stdOutput = new BufferedWriter(new
OutputStreamWriter(runtimeProcess.getOutputStream()));
read the output from the command and put my original password to command line
when password is required (Zadejte heslo pro administrator means password required in english)
System.out.println("Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
if (s.startsWith("Zadejte heslo pro administrator:")) {
stdOutput.append("password").flush();
}
}
Why if i put my original password to command line like this it didn't works? It said Access Denied, but im sure that password is right and the next question is is there any possible way how can i do it without show my password in code?
Ohhh sry i now see ur update, but it still didn't start notepad:
String[] startAsAdmin= new String [] {
"CMD.EXE",
"/C",
"echo password123 | RUNAS /profile /user:"
+ "administrator"
+ " ", "start", "notepad"};
Process runtimeProcess = Runtime.getRuntime().exec(startAsAdmin);
int processComplete = runtimeProcess.waitFor();
You Should try this:
String[] stopAdmin= new String [] {
"CMD.EXE",
"/C",
"echo password123 | RUNAS /profile /user:"
+ "administrator"
+ " ", "net", "stop", Service_Name};
Process runtimeProcess = Runtime.getRuntime().exec(stopAdmin);
Hope this helps.