I know that this question has been approached under different ways, but I have checked stackoverflow and I didn't found the answer I was looking for.
To make it simple : Is there a way to get the Time ping value to an IP server under Windows ?
I know how to check if some servers are reachable, but I would like to have precise values, like we can read on terminal.
Thank you for your help and understanding.
You can do something like this :
//The command to execute
String pingCmd = "ping " + ip + " -t";
//get the runtime to execute the command
Runtime runtime = Runtime.getRuntime();
Process process = runtime.exec(pingCmd);
//Gets the inputstream to read the output of the command
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
//reads the outputs
String inputLine = in.readLine();
while ((inputLine != null)) {
if (inputLine.length() > 0) {
........
}
inputLine = in.readLine();
}
reference
UPDATE: As per your need
public class PingDemo {
public static void main(String[] args) {
String ip = "localhost";
String time = "";
//The command to execute
String pingCmd = "ping " + ip;
//get the runtime to execute the command
Runtime runtime = Runtime.getRuntime();
try {
Process process = runtime.exec(pingCmd);
//Gets the inputstream to read the output of the command
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
//reads the outputs
String inputLine = in.readLine();
while ((inputLine != null)) {
if (inputLine.length() > 0 && inputLine.contains("time")) {
time = inputLine.substring(inputLine.indexOf("time"));
break;
}
inputLine = in.readLine();
}
System.out.println("time --> " + time);
} catch (Exception ex) {
System.out.println(ex);
}
}
}
Written in little haste.
You can invoke the ping command and read the output (as explained in the previous answer), or if you need a lower lever access (like you can do with RAW sockets), you can have a look at the jpcap java library.
As shown here, you'll want to make use of the Runtime class to shell out a ping. All that's required of you is to parse the input stream (possibly using regex to get the time ping value).
public static void main(String[] args) {
System.out.println("Enter the host to be pinged : ");
Scanner sc = new Scanner(in);
String str = sc.next();
System.out.println("Enter the no. of packets to be sent : ");
int packets = sc.nextByte();
String pingResult;
int count=0;
try{
String command = "ping -c "+ packets +" -w 10 " + str;
Process process = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
if(count==packets+4) {
pingResult = (inputLine.substring(inputLine.indexOf("=")));
pingResult = (pingResult.substring
(pingResult.indexOf("/")+1,pingResult.indexOf("/")+7));
System.out.println(pingResult + " ms");
}
count++;
}
in.close();
if(count==0)System.out.println("Wrong host entered.");
}catch(Exception e){
System.out.println("Exception caught: " + e.toString());
}
}
}
Output:
Enter the host to be pinged :
8.8.8.8
Enter the no. of packets to be sent :
5
31.406 ms
Process finished with exit code 0
Related
I have a program called darknet. It's a C-program made from Darknet.
I want to run the darknet program in a folder Darknet that looks like this:
I'm going to run darknet with Java Process Builder, but I get no responce from it when I run this code:
// Arguments
String darknetNamePath = darknet.getValue().getFilePath().replace("Darknet/", "./");
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/cameraSnap.png";
String thresholdFlag = "-thresh " + thresholds.getValue();
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File("Darknet")); // We need to stand inside the folder "Darknet"
String commandString = "detect " + configurationFlag + " " + weightsFlag + " " + imageFlag + " " + thresholdFlag;
System.out.println("darknetNamePath = " + darknetNamePath);
System.out.println("commandString = " + commandString);
processBuilder.command(darknetNamePath, commandString);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Here is my output. Why doesn't it work for me?
darknetNamePath = ./darknet
commandString = detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.8
Exited with error code : 0
But when I call darknet file via terminal, then it works.
./darknet detect cfg/yolov2-tiny.cfg weights/yolov2-tiny.weights data/cameraSnap.png -thresh 0.6
UPDATE 2:
Here is my update.
// Arguments
String darknetNamePath = darknet.getValue().getFile().getAbsolutePath();
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/cameraSnap.png";
String thresholdFlag = "-thresh " + thresholds.getValue();
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(darknetNamePath, "detect", configurationFlag, weightsFlag, imageFlag, thresholdFlag);
Process process = processBuilder.start();
if (process.getInputStream().read() == -1) {
System.out.println(darknetNamePath);
System.out.println("detect");
System.out.println(configurationFlag);
System.out.println(weightsFlag);
System.out.println(imageFlag);
System.out.println(thresholdFlag);
System.out.printf("ERROR!");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Output:
/home/dell/Dokument/GitHub/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Vaadin-DL4J-YOLO-Camera-Mail-Reporter/Darknet/darknet
detect
cfg/yolov2-tiny.cfg
weights/yolov2-tiny.weights
data/cameraSnap.png
-thresh 0.3
ERROR!
Exited with error code : 0
UPDATE 3:
This works:
// Arguments
String darkPath = darknet.getValue().getFilePath().replace("Darknet/", "./"); // We need to call ./darknet, not absolute path
String configurationFlag = configuration.getValue().getFilePath().replace("Darknet/", "");
String weightsFlag = weights.getValue().getFilePath().replace("Darknet/", "");
String imageFlag = "data/camera.png";
String thresValue = String.valueOf(thresholds.getValue());
// Process builder
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.directory(new File("Darknet")); // Important
processBuilder.command(darkPath, "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", thresValue);
processBuilder.redirectErrorStream(true); // Important
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("\nExited with error code : " + exitCode);
Your command must break all arguments into separate pieces - including thresholdFlag. It is a good idea to check if the executable exists. If it does not you should check where it is located or fix your Path variable to ensure that it can be located:
File darkpath = new File(darknetNamePath);
String [] cmd = new String[] { darkpath.getAbsolutePath(), "detect", configurationFlag, weightsFlag, imageFlag, "-thresh", String.valueOf(thresholds.getValue()) };
System.out.println("Path: "+darkpath+ " exists="+darkpath.exists());
System.out.println("exec "+Arrays.toString(cmd));
processBuilder.command(cmd);
It is also worth handling STDERR, the easiest way is to redirect STDERR=>STDOUT before calling processBuilder.start()
processBuilder.redirectErrorStream(true);
If you want Java to launch the executable without prefixing the absolute path it needs to be in one of these directories:
System.out.println("PATH COMPONENTS FOR JAVA LAUNCH:");
Arrays.asList(System.getenv("PATH").split(File.pathSeparator)).forEach(System.out::println);
You are using ProcessBuilder the wrong way. The command method takes a executable and arguments as separate strings, not a path and then another string with the actual command and all its arguments. There is no shell involved to do word splitting on the command, so you pass all your distinct arguments as one argument.
I don't have darknet, so here's a simple command using the Unix echo command:
import java.io.*;
public class ProcessBuilderTest {
public static void main(String[] args) throws Exception {
ProcessBuilder processBuilder = new ProcessBuilder();
String[] command = {"/bin/echo", "hello", "world"};
processBuilder.command(command);
Process process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
int exitCode = process.waitFor();
System.out.println("Exited with error code : " + exitCode);
}
}
When I run this, I get:
robert#saaz:~$ java ProcessBuilderTest.java
hello world
Exited with error code : 0
It's not clear to my why your command doesn't produce an error. If I give a bad command (e.g., a trailing space behind "echo"), I get an exception:
Exception in thread "main" java.io.IOException: Cannot run program "/bin/echo ": error=2, No such file or directory
This may be OS specific. Or maybe you have some other darknet executable that gets picked up.
i am writing a code to extract system info details i.e ram, processor speed and put them on a text file.
public void getSpecs(){
//run a cmd command to convert msinfo32 to .txt file
String[] command = {
"cmd",
};
Process p;
try{
p= Runtime.getRuntime().exec(command);
new Thread(new Sec(p.getErrorStream(), System.err)).start();
new Thread(new Sec(p.getInputStream(), System.out)).start();
PrintWriter pw= new PrintWriter(p.getOutputStream());
pw.println("msinfo32 /report .\\specs.txt");
pw.close();
p.waitFor();
}catch(Exception e){
e.printStackTrace();
}
}
}
This process is taking long and its converting the whole file.
msinfo32 exports the computer info into a file. It is expected to take some time as it retrieves a huge export for each computer/windows component.
I have done something similar using powershell
public static void main(String[] args) throws IOException {
//Set the commands
String cmd = "powershell.exe get-WmiObject ";
String[] win32CmdA = {"win32_processor", "win32_computerSystem", "win32_logicaldisk"};
for (String win32Cmd : win32CmdA) {
String info = runCmd(cmd + win32Cmd,
"MaxClockSpeed",
"TotalPhysicalMemory",
"DeviceID",
"FreeSpace");//Add as many atributes you want to return from powershell output
System.out.println(info); // You can use a file writer here
}
// //You can handle ErrorStream here
// String line;
// BufferedReader stderr = new BufferedReader(new InputStreamReader(
// powerShellProcess.getErrorStream()));
// while ((line = stderr.readLine()) != null) {
// System.out.println(line);
// }
}
private static String runCmd(String cmd, String... attrs) throws IOException {
Process powerShellProcess = Runtime.getRuntime().exec(cmd);
powerShellProcess.getOutputStream().close();
String line;
String result="";
BufferedReader stdout = new BufferedReader(new InputStreamReader(powerShellProcess.getInputStream()));
while ((line = stdout.readLine()) != null) {
if (line != null && line.contains(":")) {
String nameValue[] = line.split(":");
if (Arrays.asList(attrs).contains(nameValue[0].trim())) {
result+=nameValue[0] + " - " + nameValue[1] + "\n";
}
}
}
stdout.close();
return result;
}
The above code invokes the Windows Management Instrumentation (WMI) classes in powershell for specific components (processor, computerSystem and logicaldisk).
Then you define which values should be taken from the powershell output, like MaxClockSpeed, TotalPhysicalMemory, etc.
If you change the System.out.println(info); with a file writer you will have this info in a file.
Sample output (took ~3 seconds to run)
DeviceID - CPU0
MaxClockSpeed - 3401
TotalPhysicalMemory - 17053949952
DeviceID - C
FreeSpace - 56341774336
DeviceID - D
FreeSpace -
DeviceID - F
FreeSpace - 373687742464
I am trying to allow communication between one program (the program launcher, if you will) and the programs it launches via processbuilder. I have the output working fine, but the input seems to stop when it reaches the readline() method in helloworld (the created process).
Below is helloworld.java:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Scanner;
public class helloworld {
public static void main (String[] args) {
System.out.println ("println(\"Hello World!\")");
System.out.println ("getInput()");
Scanner in = new Scanner(System.in);
BufferedReader br = new BufferedReader(
new InputStreamReader(System.in));
String input = "";
try {
// wait until we have data to complete a readLine()
while (!br.ready()) {
Thread.sleep(200);
}
System.out.println("println(\"Attempting to resolve input\")");
input = br.readLine();
^This is where program hangs^
if(input != null){
System.out.println("println(\"This should appear\")");
}
System.out.println("println(\"input recieved " + input + "\")");
} catch (InterruptedException | IOException e) {
System.out.println("ConsoleInputReadTask() cancelled");
}
System.out.println("println(\"You said: " + input + "\")");
//System.out.println("println(\"You said: " + in. + "!\")");
in.close();
System.exit(0);
}
}
This is where the output (println) from the other process is recieved:
public void run() {
try {
//cfile = files[indexval].getAbsolutePath();
String[] commands =
{
"java", //Calling a java program
"-cp" , //Denoting class path
cfile.substring(0,cfile.lastIndexOf(File.separator) ), //File path
program}; //Class name
ProcessBuilder probuilder = new ProcessBuilder( commands );
//start the process
Process process = probuilder.start();
//Read out dir output
//probuilder.inheritIO(); //Can inherit all IO calls
InputStream is = process.getInputStream();
OutputStream os = process.getOutputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(os));
BufferedReader br = new BufferedReader(isr);
String line;
/*System.out.printf("Output of running %s is:\n",
Arrays.toString(commands));*/
while ((line = br.readLine()) != null) {
myController.runCommand(line, "Please enter something!", bw);
//System.out.println(line);
}
br.close();
os.close();
} catch (IOException e){
e.printStackTrace();
}
System.out.println("programclosed");
}
And here is the function that it calls:
public synchronized void runCommand(String line, Object... arguments) throws IOException {
String[] tokens;
if(line.contains("(")){
tokens = line.split("\\(",2);
switch(tokens[0]){
case "println": //Println - format println(String strng)
tokens[1] = tokens[1].substring(1, tokens[1].length() - 2);
System.out.println(tokens[1]);
break;
case "getInput": //Get input - format getInput(String command, String message, BufferedWriter br)
Scanner reader = new Scanner(System.in);
System.out.println(arguments.length);
System.out.println(((String)arguments[0]));
BufferedWriter in = ((BufferedWriter)arguments[1]);
in.write(reader.nextLine());
System.out.println("sending input");
in.flush();
reader.close();
break;
default:
System.out.println("Invalid command recieved!");
}
} else
System.out.println("Invalid command recieved!");
}
The output I recieve is:
Hello World!
2
Please enter something!
This is a test input
sending input
Attempting to resolve input
As you can see, I successfully exit the while(!br.ready()) loop, and I stop at br.readLine();
I am aware inheritIO() exist, but for this case I am using the BufferedOuput to send commands which are then parsed and sent to the switch statement, which in turn calls the corresponding function. This is because multiple processes could be launched from the process manager, think of the fun when multiple System.in calls arrive, with nothing to determine which process it is for! In addition, this allows for me to call any type of function, even those not related to println or input.
I believe the issue here is a result of the following:
BufferedReader.ready() returns true if there are any characters available to be read. It does not guarantee that there are any carriage returns among them. (docs)
BufferedReader.readLine() looks for a carriage return to complete a line. If one is not found, it blocks.
BufferedWriter.write() does not automatically write a terminating carriage return.
To test whether this is actually the problem, replace this line in runCommand():
in.write(reader.nextLine());
with:
in.write(reader.nextLine() + "\n");
I have made a cross compiler using gcc. Now I want the compile and run commands to be executed in a terminal through java program. Here is the code that I am using for this :
import java.io.BufferedReader;
import java.io.InputStreamReader;
public class Runterminal {
public static void main(String[] args) {
Process proc;
Process procRun;
String compileCommand = "aarch64-linux-g++ -std=c++14 test.cpp";
String runCommand = "aarch64-linux-objdump -d a.out";
try{
proc = Runtime.getRuntime().exec(compileCommand);
procRun = Runtime.getRuntime().exec(runCommand);
// Read the output
BufferedReader reader =
new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
while((line = reader.readLine()) != null) {
System.out.print(line + "\n");
}
proc.waitFor();
BufferedReader readero =
new BufferedReader(new InputStreamReader(procRun.getInputStream()));
String lineo = "";
while((lineo = readero.readLine()) != null) {
System.out.print(lineo + "\n");
}
procRun.waitFor();
}
catch(Exception e)
{
System.out.println("Exception occurred "+e);
}
}
}
Now my first command is executing since I could see the a.out file being generated. The second command should dump the memory contents of file and it should print in in terminal but I am not seeing any output. Can anyone tell where I am going wrong?
I would like to create a simple java app (for mac) that takes in a website and outputs my password associated with the website in Keychain.
My problem is that my app can't read the password from the output. If I manually write:
security find-internet-password -gs www.google.com
into the Terminal I get a few lines of info and then -> password: "mypassword". But in my application I only see the lines of info but the last line which should be the password is not there or null.
My code:
public static void command(){
try{
String command = "security find-internet-password -gs www.google.com";
Process child = Runtime.getRuntime().exec(command);
BufferedReader r = new BufferedReader(new InputStreamReader(child.getInputStream()));
String s;
while ((s = r.readLine()) != null) {
System.out.println(s);
}
System.out.println(r.readLine());
r.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
I'm not getting any errors but simply the code above is not showing the password. I'm using Eclipse if that matters. Thanks
The application prints:
keychain: "/Users/*username*/Library/Keychains/login.keychain"
class: "inet"
attributes:
0x00000007 <blob>="www.google.com"
0x00000008 <blob>=<NULL>
"acct"<blob>="*username*"
"atyp"<blob>="http"
"cdat"<timedate>=0x323031*numbers*3333325A00 "2011*numbers*132Z\000"
"crtr"<uint32>="rimZ"
"cusi"<sint32>=<NULL>
"desc"<blob>=<NULL>
"icmt"<blob>=<NULL>
"invi"<sint32>=<NULL>
"mdat"<timedate>=0x3230331*numbers*33834375A00 "20115*numbers*3847Z\000"
"nega"<sint32>=<NULL>
"path"<blob>="/"
"port"<uint32>=0x00000000
"prot"<blob>=<NULL>
"ptcl"<uint32>="htps"
"scrp"<sint32>=<NULL>
"sdmn"<blob>="www.google.com"
"srvr"<blob>="www.google.com"
"type"<uint32>=<NULL>
but the last line is missing and should be
password: "mypassword"
Edited
Is it the InputStreamReader that does not read the password? Is there another way to get the password?
The reason why you do not get the password in the output is that it is not printed to the stdout but to the stderr instead.
If you replace child.getInputStream() with child.getErrorStream() in your code will get you righ that Password:secret! line.
You could use e.g. the following modified version of your code:
public static boolean command(String host) {
try {
String command = "security find-internet-password -gs " + host;
Process child = Runtime.getRuntime().exec(command);
try (BufferedReader out = new BufferedReader(new InputStreamReader(
child.getInputStream()));
BufferedReader err = new BufferedReader(
new InputStreamReader(child.getErrorStream()))) {
String user = null;
String password = null;
String s;
while ((s = out.readLine()) != null) {
if (s.matches(" *\"acct\".*")) {
user = s.replaceAll("^.*=\"", "").replace("\"", "");
}
}
s = err.readLine();
password = s.replaceAll("^.*: *\"", "").replace("\"", "");
System.out.println("user: " + user);
System.out.println("pwd: " + password);
return true;
}
} catch (IOException e) {
return false;
}
}