Run netstat linux command from JAVA with grep - java

I want to run netstat -an | grep 12345 and retrieve the output to find out if a port is empty and ready to use. I have tried
TRY1:
System.out.println("RUNNING ==> "+command);
try
{
Process process = Runtime.getRuntime().exec("netstat -an | grep 4324");
InputStream in = process.getInputStream();
File tmp = File.createTempFile("allConnections","txt");
byte[] buf = new byte[256];
OutputStream outputConnectionsToFile = new FileOutputStream(tmp);
int numbytes = 0;
while ((numbytes = in.read(buf, 0, 256)) != -1)
{
outputConnectionsToFile.write(buf, 0, numbytes);
}
System.out.println("File is present at "+tmp.getAbsolutePath());
}
catch (Exception e)
{
e.printStackTrace(System.err);
}
i see 12k results, like i was doing netstat -an without grep
TRY2:
public static ArrayList<String> exec_command_dont_wait(String command) throws IOException, InterruptedException
{
//String[] arrayExplodedArguments = command.split(" ");
ArrayList<String> returnHolder = new ArrayList<String>();
List<String> listCommands = new ArrayList<String>();
String[] arrayExplodedCommands = command.split(" ");
for(String element : arrayExplodedCommands)
{
listCommands.add(element);
System.out.println(element+"\n");
}
System.exit(0);
ProcessBuilder ps = new ProcessBuilder(listCommands);
ps.redirectErrorStream(true);
Process p = ps.start();
BufferedReader buffer = new BufferedReader(new InputStreamReader(p.getInputStream()));
//p.waitFor();
String line = new String();
while((line = buffer.readLine()) != null)
{
returnHolder.add(line);
//System.out.println(line);
}
return returnHolder;
}
i see 12k results, like i was doing netstat -an without grep , never to mention that i have to comment //p.waitFor(); and i don't know why.
How do i a simple netstat command with grep and retrieve the results?
Is there a simple command/function like in PHP and retrieve the results? Like 'exec()', really love that function.
What is the differance between running with p.waitFor() and without it. I mean i understand that JAVA waits for the process to finsish, but netstat seems to never finish, i waited 2 minutes. A simple curl finishes quicly.
Example
netstat -an | grep 4352
tcp 0 0 192.99.3.11:43529 118.32.42.29:22 ESTABLISHED
tcp 0 0 192.99.3.11:43522 15.139.118.57:22 ESTABLISHED
tcp 0 0 192.99.3.11:43521 116.322.199.10:22 ESTABLISHED
Thank you.

Related

How to write and run terminal command to be execute in java program

String str;
Process p;
try {
String command = "wmctrl -l|awk '{$1=\"\"; $2=\"\"; $3=\"\"; print}'";
p = Runtime.getRuntime().exec(command);
BufferedReader br = new BufferedReader(
new InputStreamReader(p.getInputStream()));
while ((str = br.readLine()) != null) {
activeWindowtitles.add(str);
System.out.println(str);
}
p.waitFor();
p.destroy();
} catch (Exception ex) {
}
I am writing a java code to get all applications name in Linux system. I found a command to achieve this. I ran this command in Terminal and it works fine. But it is not working in Java code as i want only applications name instead of other details. The command is "wmctrl -l | awk '{$1=""; $2=""; $3=""; print}'"
I am getting full output after executing this in java code.
Please tell me how to write this command properly..
Thanks
Personally I would put the wmctrl command in a script and do something like this:
public static List<String> getRunningApps(String executablePath) throws IOException, InterruptedException {
final String ERR_LOG_PATH = "stderr.log";
List<String> result = new ArrayList<>();
ProcessBuilder pb = new ProcessBuilder(executablePath);
pb.redirectError(new File(ERR_LOG_PATH));
Process p = pb.start();
int exitCode = p.waitFor();
if (exitCode != 0) {
throw new RuntimeException(String.format("Error get apps. Check error log %s%n", ERR_LOG_PATH));
}
try (Scanner s = new Scanner(p.getInputStream())) {
while (s.hasNextLine()) {
result.add(s.nextLine().trim());
}
}
return result;
}
That way you can tweak it more easily and keep your code cleaner. The script I used was:
#!/bin/bash
wmctrl -l | awk '{$1=""; $2=""; $3=""; print}'

how to execute command "ps -eaf | grep myprocess" in java

I googled and checked the SO if there is any code to find PID of any other process.
There is a solution to create a shell script with the command "ps -eaf | grep myprocess" in it and executing that script from java.
But I want to execute using java ProcessBuilder or Runtime methods. Below is the code that I have tried which is not giving me null as output.
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String command = "ps -ef | grep myProcess";
try {
// p = new ProcessBuilder(command).start();
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
The output for the command is :
java TestShellCommand
The input stream is null.
{sdc#ip-172-31-32-49}[26] echo $?
0
Please let me know if there is any error in my code as when I search manually from shell i do get the expected output as below:
ps -ef | grep myProcess
root 7433 1 0 10:33 ? 00:00:00 myProcess hello
sdc 19894 14130 0 11:24 pts/7 00:00:00 grep myProcess
[UPDATED CODE - Without the grep command]
import java.io.*;
public class TestShellCommand {
public static void main(String args[]) {
Process p = null;
String [] command = {"ps", "-eaf"};
try {
p = Runtime.getRuntime().exec(command);
BufferedReader br[] = new BufferedReader[2];
br[1] = new BufferedReader(new InputStreamReader(p.getErrorStream()));
br[0] = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
if(br[0].readLine() == null){
System.out.println("The input stream is null.");
}
while ((line = br[0].readLine()) != null) {
System.out.println(line);
}
// Then code to find by process name by using string methods ...
try {
br[0].close();
} catch (Exception a) {
a.printStackTrace();
}
try {
br[1].close();
} catch (Exception a) {
a.printStackTrace();
}
} catch (Exception grrr) {
grrr.printStackTrace();
} finally {
try {
closeStreams(p);
p.destroy();
} catch (Exception r) {
r.printStackTrace();
}
}
}
static void closeStreams(Process p) throws IOException {
p.getInputStream().close();
p.getOutputStream().close();
p.getErrorStream().close();
}
}
I have added the code that is working, when I am passing command as:
new String[]{"/bin/sh","-c", "ps -eaf | grep "+ "myProcess" +" | grep -v grep"} - Empty response.
new String[] {"ps", "-eaf", "grep -m 1 myProcess", "awk -F ' ' '{print $2}' "} - Empty response.
Thanks in advance for any leads.
As #Slimo answer indicates you must launch a shell to execute a shell command (the pipe), and read the error stream to determine what may have gone wrong.
Launching subprocess without using waitFor() or consuming stdout and stderr at SAME time can lead to issues, use file redirect or as in this example merge stderr -> stdout and read one stream only:
String procname = "myProcess";
String[] cmd = new String[]{"bash","-c", "ps -eaf | grep "+procname+" | grep -v grep"}
ProcessBuilder pb = new ProcessBuilder(cmd);
pb.redirectErrorStream(true);
Process process = pb.start();
process.getInputStream().transferTo(System.out);
int rc = process.waitFor();
if (rc != 0)
throw new RuntimeException("Failed rc="+rc+" cmd="+Arrays.toString(cmd));
In later JDK you don't need ProcessBuilder, you may find all the process attributes in the data-structures returned by ProcessHandle:
ProcessHandle.allProcesses()
.filter(ph -> ph.info().command().isPresent() && ph.info().command().get().contains(procname))
.forEach(ph -> System.out.println("PID: "+ph.pid()+" command: "+ph.info().command()))
Your problem is that you are trying to use the pipe in your command, so you need a shell to execute it. You can use the following command:
p = new ProcessBuilder("/bin/sh", "-c", "ps -aux | grep myProcess").start();
You can read more here: Using Java ProcessBuilder to Execute a Piped Command
To test it, I started top in a shell and run the command with it as the grep pattern. Here is the output I got:
<edited> 139890 0.4 0.0 23640 4376 pts/0 S+ 16:05 0:00 top
<edited> 139945 0.0 0.0 20996 3448 ? S 16:06 0:00 /bin/bash -c ps -aux | grep top
<edited> 139947 0.0 0.0 20536 2776 ? S 16:06 0:00 grep top
Based on your comment, I suggest you first run the commands in a shell to see the output and check to see if it matches that from the Java program. I guess myProcess is only a placeholder for the actual process to check.
One thing which I noticed is that when running htop from a snap, and using the above code to grep after htop will return answers like in your comment, but grepping by top will include the actual process. I also checked with gedit and it looks like grep with gedit returns like in your case, but using only edit will return the actual process. Not sure what is the problem in this case.

Check if a linux command outputs an empty string

I want to check if a port is being used or not. I've used the command: netstat -an | grep <port_no> | grep -i listen. When I compare its output by running, if(message_port_check.equals(null)), it always returns null. How do I know if the port is open or not ?
This is what I've tried,
String port_no = textField_3.getText().toString();
String[] command_port = {
"/bin/sh",
"-c",
"netstat -an | grep " + port_no + " | grep -i listen"
};
try {
ProcessBuilder builder = new ProcessBuilder(command_port);
builder.redirectErrorStream(true);
Process p = builder.start();
BufferedReader r = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuffer buffer = new StringBuffer();
String line = "";
while (true)
{
buffer.append(line).append("\n");
line = r.readLine();
if (line == null) { break; }
}
message_port= buffer.toString();
p.waitFor();
r.close();
}
catch (IOException e1)
{
e1.printStackTrace();
}
catch (InterruptedException e1)
{
e1.printStackTrace();
}
if(message_port_check.equals(null))
rdbtn_port_free.setSelected(true);
else
rdbtn_port_notfree.setSelected(true);
I'd use -z test:
$ output=$(netstat -an | grep your_port | grep -i listen)
$ if [ -z "$output" ] ; then echo empty ; fi
empty
You could use nc instead as shown in this reply. Then you just need to check the return value.
Of course in Java, the solution in the platform-independent spirit would be to try to connect/bind to the port using the standard library instead of relying on external Linux binaries. Some variants are shown here.

grep command is not working with git blame files and git log for a revision

I am trying to run below code:
public class StandOnLinux {
public static void main(String[] args) throws IOException {
//String commandToBeExecuted = "git blame '"+files[i]+"' | grep "+revision+" | awk '{print $7}'";
//String commandToBeExecuted = "git --git-dir D:\\code_coverage\\.git blame src\\RunCodeCoverage.java | grep 'e4ecfbe'"; git blame --git-dir D:/code_coverage/.git src/RunCodeCoverage.java| grep 59e3fdc | gawk '{print $7}'
String commandToBeExecuted = "git blame StandOnLinux.java --grep=\"e8a93e7d\"";
String temp = "";
File file = new File("C:/Program Files (x86)/Git/bin");
System.out.println(commandToBeExecuted);
Process p = Runtime.getRuntime().exec(commandToBeExecuted);
//Process p = Runtime.getRuntime().exec(new String[]{"cmd", "/c", commandToBeExecuted});
//Process p =Runtime.getRuntime().exec(commandToBeExecuted, null, file);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(
p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(
p.getErrorStream()));
while((temp = stdInput.readLine()) != null) {
System.out.println(temp);
}
while((temp = stdError.readLine()) != null) {
System.out.println(temp);
}
}
}
But this gives me results without grepping the output as mentioned in grep.
Can anyone tell what is wrong i am doing in this code?
Running this code on Linux machine.
For a pipe to work, you might try to execute the commands in a separate shell, as in "How to make pipes work with Runtime.exec()?"
String[] cmd = {
"/bin/sh",
"-c",
"git blame StandOnLinux.java | grep e8a93e7d"
};
Process p = Runtime.getRuntime().exec(cmd);
Make sure the default $PATH does include git.

List Open TCP connections in Java

I was wondering how I could list all the TCP connections on my system which are open using Java. I am using CentOS.
I do not have any clue on where to start also. Any pointers would be helpful.
Thanks in advance
Thanks for the tips
I have to do something like this
Q) Identify any new established connections for all tcp ports that are currently listening
and continue to poll every 5 seconds. The script should terminate when there are no longer any established connections.
public class TCPConnections {
public HashSet<Integer> establishedConnections = new HashSet<Integer>();
public HashSet<Integer> listeningConnections = new HashSet<Integer>();
public static void main(String[] args) {
// TODO Auto-generated method stub
TCPConnections tcpConnections = new TCPConnections();
try{
do{
tcpConnections.getListeningConnections();
Thread.sleep(5000);
tcpConnections.getEstablishedConnections();
}while(!tcpConnections.establishedConnections.isEmpty());
}
catch(Exception ex){
ex.printStackTrace();
}
}
public void getEstablishedConnections(){
String netstat = new String();
try {
String line;
establishedConnections = new HashSet<Integer>();
String[] cmd = {
"/bin/sh",
"-c",
"netstat -atn | grep -w tcp | grep ESTABLISHED"
};
java.lang.Process p = Runtime.getRuntime().exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
String[] portNo = line.split("\\s+");
if(portNo[3] != null && !portNo[3].equalsIgnoreCase(" ")){
String str = portNo[3].split(":")[1];
if( str != null && str.matches("[0-9]+")){
establishedConnections.add(Integer.parseInt(str));
if(listeningConnections.contains(Integer.parseInt(str))){listeningConnections.remove(Integer.parseInt(str));
System.out.println(" New connection established on port : "+Integer.parseInt(str));
}
}
}
netstat = netstat + " \n" + line;
}
System.out.println(netstat);
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
public void getListeningConnections(){
String netstat = new String();
try {
String line;
listeningConnections = new HashSet<Integer>();
String[] cmd = {
"/bin/sh",
"-c",
"netstat -atn | grep -w tcp | grep LISTEN"
};
java.lang.Process p = Runtime.getRuntime().exec(cmd);
BufferedReader input = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = input.readLine()) != null) {
String[] portNo = line.split("\\s+");
if(portNo[3] != null && !portNo[3].equalsIgnoreCase(" ")){
String str = portNo[3].split(":")[1];
if( str != null && str.matches("[0-9]+")){
listeningConnections.add(Integer.parseInt(str));
}
}
netstat = netstat + " \n" + line;
}
System.out.println(netstat);
input.close();
} catch (Exception err) {
err.printStackTrace();
}
}
}
The problem I face is that few ports are always in the established state and few are always in the Listen state so that the do-while loop runs forever. Kindly help me to solve this issue.
There doesn't seem to be anything built-in to Java to support this, which isn't surprising because netstat-like functionality is OS-dependent.
You have two other options:
1) Parse the output of netstat:
$ netstat -tn
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 192.168.1.140:48352 74.125.225.134:80 ESTABLISHED
2) Parse /proc/net/tcp (and tcp6, udp, udp6, unix, if you care):
$ cat /proc/net/tcp
sl local_address rem_address st tx_queue rx_queue tr tm->when retrnsmt uid timeout inode
0: 0100007F:0277 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 17120 1 ffff8800797c4700 100 0 0 10 0
1: 0100007F:0019 00000000:0000 0A 00000000:00000000 00:00000000 00000000 0 0 14821 1 ffff8800797c4000 100 0 0 10 0
2: 8C01A8C0:BCE0 86E17D4A:0050 01 00000000:00000000 00:00000000 00000000 1000 0 20164 1 ffff8800797c4e00 24 0 0 10 -1
This may appear more daunting, but would be the preferred method, as it doesn't rely upon netstat being present (and in your PATH, etc.)
You could use SNMP to get the TCPConnTable or TCPConnectionTable, whichever is supported.
There is a Java SNMP library called NetSNMP, no doubt others as well.

Categories