I was developing a project in Java to scan the File System and this involves executing dos commands in java with administrative privilege.
I already wrote the program to execute simple dos commands in Java.
public class doscmd {
public static void main(String args[]) {
try {
Process p = Runtime.getRuntime().exec("cmd /C dir");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
while (line != null) {
System.out.println(line);
line = reader.readLine();
}
} catch (IOException e1) {
} catch (InterruptedException e2) {
}
System.out.println("Done");
}
}
But as you can see this does not allow to execute elevated commands.
I am developing the project in Netbeans IDE and i was hoping if any of you folks could tell me if there is any code in java to get admin privilege instead of converting the file to .exe and then clicking run as administrator.
Your JVM needs to be running with admin-privileges in order to start a process with admin-privileges.
Build your code and run it as an administrator - every process spawned by your class will have administrator privileges as well.
try this code, it works for me:
String command = "cmd /c start cmd.exe";
Process child = Runtime.getRuntime().exec(command);
OutputStream output = child.getOutputStream();
output .write("cd C:/ /r/n".getBytes());
output .flush();
output .write("DIR /r/n".getBytes());
output .close();
Related
Here is my runCommand that takes Linux command input as a string
public static ArrayList<String> runCommand(String command) {
ArrayList<String> arrayList = new ArrayList<>();
try {
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader =
new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
arrayList.add(line);
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : "+exitCode);
System.out.println();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return arrayList;
}
It is working great with normal command like ls or sudo lsof -t -i:132 or other. Even tailing live log from ping google.com. My socat command
sudo SOCAT_SOCKADDR=192.168.11.131 socat -d -d -T 10 UDP4-LISTEN:132,reuseaddr,fork UDP4:192.168.11.130:130,bind=192.168.11.131:133
(-d -d for verbose) in terminal creates socat process and tails the logs in terminals like incoming connection or connection status. but if I run this command via my runCommand(), this isn't printing anything in the terminal where the java jar application is running. And it worked fine for other cases of commands.
I tried placing the process.waitFor() before reading the loop but nothing. What is the problem here? my main goal is to parse the live-tailed log and do some other stuff depending on that.
I would like to run a hidden script file that resides in the current location using process builder. with the following code
// System.out.println("line"+reader.readLine());
ProcessBuilder builder = new ProcessBuilder(shfile.getAbsolutePath());
builder.redirectErrorStream(true);
Process process = builder.start();
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String output = null;
System.out.println("out"); //===printing this
while (null != (output = br.readLine()))
{
System.out.println("in"); //not printing this
System.out.println(">>"+output);
}
int rs = process.waitFor();
but it hangs in the br.readline()..
but when I run the same script file using the following command in terminal
sh .script.sh
it executes and gives me the expected results
I looked into all the loops in the forum everyone asks to handle input stream and error stream in threads or do a redirect error stream. I have added a redirect error stream but still it hangs.
when i press ctrl+c it prints the initial lines of the output and exits.
Content of my script file
#!/bin/sh
cd /home/ats/cloudripper/lke_factory_asb_v2/lk_assets_factory_release/
sh ./LKE_run_Diablo.sh 0a0e0c3dc893
So how to handle this situation.
Process builder have special API to redirect child process input, output and error streams. See documentation
If you need both child and parent process to use same console you should use INHERIT mode redirection. An example:
public class ChildProcessOutputProxy {
public static void main(String[] args) {
ProcessBuilder builder = new ProcessBuilder("whoami");
builder.redirectOutput(Redirect.INHERIT);
builder.redirectErrorStream(true);
try {
var child = builder.start();
child.waitFor();
} catch (IOException e) {
System.err.println(e.getMessage());
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
I already create the .sh file, and the inside is:
sudo iptables --flush
sudo iptables -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j DROP
It works normally when I run it on the terminal, but when I use processbuilder, it didn't do anything. No error, but didn't happen anything, this is the code on my java:
Process pb = new ProcessBuilder("/bin/bash","/my/file.sh").start();
I already looking for the answer, but I still failed to run the .sh file, even I do the same thing with people that already done it.
Sorry if this is a bad question, thank you.
Are you sure that the bash is not run? Do you checked the Process object returned by the startmethod? You can get the output value, the output stream, etc. from this objects.
Check your streams and exitvalue for errors... sudo is probably the problem here.
Not necessarily the best code but it gets the job done. Executes a process, takes the process.streams and prints them to System.out. Might helpt to find out what the issue actually is atlest.
ProcessBuilder pb = new ProcessBuilder(args);
pb.redirectErrorStream(true);
final Process proc = pb.start();
final StringBuilder builder = new StringBuilder("Process output");
final Thread logThread = new Thread() {
#Override
public void run() {
InputStream is = proc.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
try {
String line;
do {
line = reader.readLine();
builder.append("");
builder.append(line == null ? "" : line);
builder.append("<br/>");
} while(line != null);
} catch (IOException e) {
builder.append("Exception! ").append(e.getMessage());
} finally {
try {
reader.close();
} catch (IOException e) {
builder.append("Exception! ").append(e.getMessage());
}
}
}
};
logThread.start();
int retVal = proc.waitFor();
System.out.println(builder.toString());
From Java API Runtime : http://docs.oracle.com/javase/7/docs/api/java/lang/Runtime.html
// Java runtime
Runtime runtime = Runtime.getRuntime();
// Command
String[] command = {"/bin/bash", "/my/file.sh"};
// Process
Process process = runtime.exec(command);
Also you should be careful with sudo commands that may ask for root password.
File wd = new File("/bin");
Process proc = null;
try {
proc = Runtime.getRuntime().exec("/bin/bash", null, wd);
} catch (IOException e) {
logger.info(e);
e.printStackTrace();
}
if (proc != null) {
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(proc.getOutputStream())), true);
//out.println("su - root");
out.println("cp /usr/rock/Masterfile.xls /usr/rock/generatedfile/");
out.println("mv /usr/rock/generatedfile/Masterfile.xls /usr/rock/generatedfile/userid.xls");
try {
String line;
while ((line = in.readLine()) != null) {
logger.info(line);
}
proc.waitFor();
in.close();
out.close();
proc.destroy();
} catch (Exception e) {
logger.info(e);
e.printStackTrace();
}
}
I am trying to copy master file and want to rename according to the userid. Code does not showing any error but i dont see any file in the folder i specify. I tried with sudo root command even its not copying and renaming the file. How should i do in order to run copy and rename command to run successfully from java program.
You're not reading from the process's standard error. So if your cp and mv commands are reporting errors, you won't be seeing them.
It's possible to read from the process's standard error, but that's complicated if you're using Runtime.getRuntime().exec() because reading from standard error needs to be done in a separate thread to reading from standard output.
Java 5 introduced a new class for running external processes: ProcessBuilder. In my opinion, the single biggest advantage of a ProcessBuilder is that you can redirect the standard error of the process into its standard output. That leaves you with only one stream to read from, and hence no need for a separate thread.
I would recommend replacing your use of Runtime.getRuntime().exec(...) with the following:
ProcessBuilder builder = new ProcessBuilder("/bin/bash");
builder.directory(wd);
builder.redirectErrorStream(true);
proc = builder.start();
If the files aren't being copied, then chances are that cp and mv are reporting errors. Making this change should hopefully allow you to see the errors being reported.
I am attempting to get output of a shell / bash script, that is run from a JAVA program, although I am not having much luck, the code is as follows:
GetStats(winhostname);
public static String winhostname "cmd /c hostname";
public static void GetStats(String operation)
{
try
{
Process p=Runtime.getRuntime().exec(operation);
p.waitFor();
BufferedReader reader=new BufferedReader(new InputStreamReader(p.getInputStream()));
String line=reader.readLine();
while(line!=null)
{
System.out.println(line);
if (operation.equals("winhostname"))
{
winhostnamevalue = line;
}
line=reader.readLine();
}
}
catch(IOException e1) {}
catch(InterruptedException e2) {}
}
This works on Windows fine, so I changed the value of winhostname to "sh namecheck.sh" (which simply echos the hostname) and the shell script is located in the same directory as the java / class file. Although when run I get a blank result, not null, just blank.
Try /bin/sh. I do not sure that when you are running program from java it has all environment that you have when you are working with shell.
If it does not work try to run some command (e.g. pwd). But provide full path. Then, when it works try your command again and be sure that it can find your script. For the beginning use absolute path. Then move to relative path.
Good luck.