Running Grep command from java - java

I want to run grep command from java.
Here is what I had tried. Please let me know, why it is not displaying ouput.
public static void main(String args[]) throws IOException{
Runtime rt = Runtime.getRuntime();
String[] cmd = { "/bin/sh", "-c", "grep 'Report Process started' server.log|wc -l" };
Process proc = rt.exec(cmd);
BufferedReader is = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line;
while ((line = is.readLine()) != null) {
System.out.println(line);
}
System.out.println("Done");
}

You don't need to pipe grep's output to wc -l. Just use grep -c like this:
String[] cmd = {"/bin/sh", "-c", "grep -c 'Report Process started' /path/to/server.log"};
Though I must say that doing this right inside Java is much cleaner. Consider code like this:
String logdata = new Scanner(new File("/path/to/server.log")).useDelimiter("\\Z").next();
final String needle = "Report Process started";
int occurrences = 0;
int index = 0;
while (index < logdata.length() && (index = logdata.indexOf(needle, index)) >= 0) {
occurrences++;
index += needle.length();
}

You must check for any errors.
private static void printStream(InputStream in) throws IOException {
BufferedReader is = new BufferedReader(new InputStreamReader(in));
String line;
while ((line = is.readLine()) != null) {
System.out.println(line);
}
}
public static void main(String args[]) {
try {
Runtime rt = Runtime.getRuntime();
String[] cmd = {"/bin/sh", "-c", "grep 'Report Process started' server.log|wc -l"};
Process proc = rt.exec(cmd);
printStream(proc.getInputStream());
System.out.println("Error : ");
printStream(proc.getErrorStream());
} catch (Exception ex) {
ex.printStackTrace();
}
}

Related

Achieving Terminal Commands using processbuilder

I am trying to execute the command present as the solution in the following link:https://apple.stackexchange.com/questions/258020/why-does-find-certificates-have-some-missing I am executing the command using processbuilder in java but for some reason i am not able to get the value from stringbuffer eventhough the command runs perfectly in terminal.
This is may java command:
ArrayList<String> lcommands = new ArrayList<String>();
ArrayList<ArrayList<String>> lcommandsets = new ArrayList<ArrayList<String>>();
lcommands = new ArrayList<String>();
//lcommands.add("security find-identity -p codesigning -v");
// lcommands.add("security");
// lcommands.add("find-identity");
// lcommands.add("-p");
// lcommands.add("codesigning");
// lcommands.add("-v");
lcommands.add("security find-certificate -a -p codesign ~/Library/Keychains/login.keychain \\\n| awk '/-----BEGIN CERTIFICATE-----/ { cert = \"\" } \\\n{ cert = cert $0 \"\\n\" } \\\n/-----END CERTIFICATE-----/ { \\\nopenssl = \"openssl x509 -text -enddate -noout\"; \\\nprint cert | openssl; \\\nclose(openssl) \\\n}'");
// lcommands.add("find-certificate");
// lcommands.add("-a");
// lcommands.add("-p");
// lcommands.add("codesign");
//lcommands.add("~/Library/Keychains/login.keychain \\\n| awk '/-----BEGIN CERTIFICATE-----/ { cert = \"\" } \\\n{ cert = cert $0 \"\\n\" } \\\n/-----END CERTIFICATE-----/ { \\\nopenssl = \"openssl x509 -text -enddate -noout\"; \\");
// lcommands.add("~/Library/Keychains/login.keychain \\");
// lcommands.add("| awk '/-----BEGIN CERTIFICATE-----/ { cert = \"\" } \\");
// lcommands.add("{ cert = cert $0 \"\\n\" } \\");
// lcommands.add("/-----END CERTIFICATE-----/ { \\");
// lcommands.add("openssl = \"openssl x509 -text -enddate -noout\"; \\");
// lcommands.add("print cert | openssl; \\");
// lcommands.add("close(openssl) \\");
// lcommands.add("}'");
System.out.println();
lcommandsets.add(lcommands);
for (int i = 0; i < lcommandsets.size(); i++) {
Process process = null;
try {
ArrayList lruncommands = (ArrayList) lcommandsets.get(i);
ProcessBuilder lprocessbuilder = new ProcessBuilder(lruncommands);
// lprocessbuilder.directory(new File("/Users/"));
// lprocessbuilder.directory(new File("/Users/Admin/Library/Keychains"));
lprocessbuilder.redirectErrorStream(true);
process = lprocessbuilder.start();
try (BufferedReader bri = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
String line;
while ((line = bri.readLine()) != null) {
//System.out.println(line);
if (line.contains(":") && line.contains("(")) {
lcertname = line.substring(line.indexOf(":") + 1, line.indexOf("(")).trim();
lteamid = line.substring(line.indexOf("(") + 1, line.lastIndexOf(")")).trim();
String ltrim=line.trim().substring(line.indexOf(')')+1);
luuid=ltrim.substring(0,ltrim.indexOf(" "));
//System.out.println("");
ArrayList<String> lval=new ArrayList<String>();
lval.add(0, luuid);
lval.add(1, lcertname);
lkeys.put(lteamid,lval );
}
}
} catch (Exception e) {
e.printStackTrace();
}
All the commented lines are the different combinations that i tried.If anyone knows how to split the command,it would be verymuch useful.Thanks in advance.
The problem seems to be the "pipe" inside your command.
As far as I know you have to start a shell (cmd on windows) and pass your command-string as a parameter.
The following code starts a "git bash" under windows and executes the command "dig www.kde.org | grep kde".
public static void main(String[] args) throws IOException {
ArrayList<String> lst = new ArrayList<String>();
lst.add("c:\\Anwendungen\\git\\bin\\bash");
lst.add("-c");
lst.add("dig www.kde.org |grep kde");
ProcessBuilder bld = new ProcessBuilder(lst);
Process proc = bld.start();
BufferedReader bfRdr = new BufferedReader(new InputStreamReader(proc.getInputStream()));
bfRdr.lines().forEach((String line) -> {
System.out.println(line);
});
}
As an alternative you can try using another approach that I have used in my project.
public static void main(String args[]) throws IOException
{
String line = null;
InputStream in = null;
String logFilePath = System.getProperty("user.dir") + "/logs/log1.log";
String s1 = "grep -n 'Start' " + logFilePath + " | tail -n 1 | cut -d : -f 1";
String[] cmd = { "/bin/sh", "-c", s1 };
try {
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec(cmd);
in = proc.getInputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(in));
line = br.readLine();
// operations to be performed on matched line
} finally {
if (in != null)
in.close();
}
}
}

How can I close a Java application from another Java application?

I am using the following code for running an application:
private void RunApp2() throws IOException
{
StringBuilder sb = new StringBuilder();
String filePath = System.getProperty("user.dir");
String jarfile = filePath + "\\MyAppV2.jar";
File f = new File(jarfile);
if(f.exists() && !f.isDirectory()) {
// do something
}
else
{
AreThereProblem = true;
}
try { // jarname arguments has to be saperated by spaces
Process process = Runtime.getRuntime().exec("cmd.exe start /C java -jar \""+jarfile + "\"");
//.exec("cmd.exe /C start dir java -jar "+jarfile+" "+name+" "+id+" dir");
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream ()));
String line = null;
while ((line = br.readLine()) != null){
sb.append(line).append("\n");
}
System.out.println("Console OUTPUT : \n"+sb.toString());
//process.destroy();
}catch (Exception e){
lblInformation.setText(e.getMessage());
}
}
But how can I close MyAppV2.jar application if it is already running before I'm running it again?

Java ProcessBuilder to start multiple java processes

Can I spawn multiple different JVMs given the same Main.class, arguments and VM options?
Is it possible to do it with the ProcessBuilder?
Here is a basic example using Process that starts 10 different JVM process:
for (int i = 0; i < 10; i++) {
new Thread(new Runnable() {
public void run() {
try {
//start a new jvm with 256m of memory with the MyClass passing 2 parameters
String cmd = "java -Xmx256M -cp myjar.jar com.mymainclass.MyClass par1 par2";
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = br.readLine();
while (line != null) {
line = br.readLine();
}
br = new BufferedReader(new InputStreamReader(p.getErrorStream()));
line = br.readLine();
while (line != null) {
line = br.readLine();
}
} catch (IOException e) {
}
}
}).start();
}

Fetch and store output from a subprocess in Java

I'm working on something that requires me to start to subprocess(command prompt) and execute some commands on it. I need to fetch the output from the subprocess and store it in a file or String.
here's what I have done so far, and it doesn't work:
public static void main(String args[])
{
try
{
Runtime RT = Runtime.getRuntime();
String command = "cmd /c start javap java.lang.String";
File file = new File("write.txt");
Writer output = new BufferedWriter(new FileWriter(file));
BufferedReader br = new(BufferedReader(newInputStreamReader(RT.exec(command).getInputStream()));
String temp = br.readLine();
while(!temp.equals(null))
{
output.write(temp);
temp = br.readLine();
}
output.close();
RT.exec("exit");
}
catch(Exception e)
{
System.out.println(e);
}
}
Start changing this:
new(BufferedReader(newInputStreamReader(
To:
new BufferedReader(new InputStreamReader(
Compile and see if you still have the problem
edit
Also, there is a good reason why you shouldn't catch Exception, you also catch programming errors like a NullPointerException
while( !temp.equals(null)) { //Throws NullPointerExceptin when temp is null
Change it with:
while( temp != null ) { //!temp.equals(null)) {
Finally you don't have to "exit" since you're not inside the cmd really.
Corrected version
This version runs as you intend:
import java.io.*;
class Rt {
public static void main(String args[]) throws Exception {
Runtime RT = Runtime.getRuntime();
String command = "javap java.lang.String" ;
File file = new File("write.txt");
Writer output = new BufferedWriter(new FileWriter(file));
BufferedReader br = new BufferedReader(new InputStreamReader(RT.exec(command).getInputStream()));
String temp = br.readLine();
while( temp != null ) { //!temp.equals(null)) {
output.write(temp);
temp = br.readLine();
}
output.close();
//RT.exec("exit");
}
}
edit
Final remarks:
Since Java 1.5 the preferred way to invoke a command is using ProcessBuilder and it is better if you use an array of strings instead of a single string ( or varargs ).
When you're building your output you can get rid of the file object and pass the file name directly to the filewriter.
While reading the line you can assign and evaluate in the condition.
Java's coding conventions suggest to use the opening brace in the same like.
This would be my version of your code:
class Rt {
public static void main(String args[]) throws Exception {
Writer output = new BufferedWriter(new FileWriter ( "write.txt"));
InputStream in = new ProcessBuilder("javap", "java.lang.String").start().getInputStream();
BufferedReader br = new BufferedReader( new InputStreamReader(in));
String line = null;
while( ( line = br.readLine() ) != null ) {
output.write( line );
}
output.close();
}
}
It might need still some work, but I hope it helps you.
Here is an example which should work:
StringBuffer outStream = new StringBuffer();
StringBuffer errStream = new StringBuffer();
Runtime runtime = Runtime.getRuntime();
Process process = null;
try {
process = runtime.exec(command);
} catch (IOException ex) {
ex.printStackTrace();
return;
}
InputStream outIs = process.getInputStream();
MonitorOutputThread sout = new MonitorOutputThread(outIs, outStream);
sout.run();
InputStream errIs = process.getErrorStream();
MonitorOutputThread serr = new MonitorOutputThread(errIs, errStream);
serr.run();
while (sout.isAlive() || serr.isAlive()) {
try {
sleep(100);
} catch (InterruptedException ex) {
ex.printStackTrace();
// ignore
}
}
And the code for MonitorOutputThread
private class MonitorOutputThread extends Thread {
private final InputStream is;
private final StringBuffer output;
public MonitorOutputThread(InputStream is, StringBuffer output) {
this.is = is;
this.output = output;
}
#Override
public void run() {
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);
String line = null;
try {
while ((line = br.readLine()) != null) {
output.append(line);
output.append(LINE_SEPARATOR);
}
if (output.length() >= 1) {
char lastChar = output.charAt(output.length() - 1);
if (lastChar == '\n') {
output.deleteCharAt(output.length() - 1);
}
}
} catch (IOException ex) {
ex.printStackTrace();
return;
}
}
}
This should catch both the standard output and standard error of the command.
DevDaily has a simple example of how to work with Process class.
See the snippet:
import java.io.*;
public class JavaRunCommand {
public static void main(String args[]) {
String s = null;
try {
// run the Unix "ps -ef" command
// using the Runtime exec method:
Process p = Runtime.getRuntime().exec("ps -ef");
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
System.exit(0);
}
catch (IOException e) {
System.out.println("exception happened - here's what I know: ");
e.printStackTrace();
System.exit(-1);
}
}
}
or even check this code I've writen some time ago

Once I have the name of a SQLServer, how do I list its databases in java?

I am trying to populate a drop down list of SQLServers on a network using the osql -L command through Java. The user will then choose a server and type in a username and password. I also need to populate another list with the databases on that server. Any ideas on how I can implement that using java? If possible, please give java code.
Thank you.
public class SQL implements ActionListener{
public static void main(String[] args) throws Exception{
String[] str = new String[] {"cmd.exe", "/c", "osql", "-L" };
Runtime rt = Runtime.getRuntime();
try{
Process p = rt.exec(str);
InputStream is =p.getInputStream();
InputStream err = p.getErrorStream();
InputStreamReader in = new InputStreamReader(is);
StringBuffer sb = new StringBuffer();
BufferedReader buff = new BufferedReader(in);
//clearing away white space and "Servers"
buff.readLine();
buff.readLine();
String line = buff.readLine();
JComboBox servers = new JComboBox();
while (line != null){
servers.addItem(line.trim());
line =buff.readLine();
}
SQL sql = new SQL();
servers.addActionListener(sql);
JOptionPane.showMessageDialog(null, servers);
}catch( Exception ex )
{
ex.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
JComboBox cb = (JComboBox)e.getSource();
String ser = (String)cb.getSelectedItem();
}
}
This website helped a lot.
http://www.cyberciti.biz/faq/howto-ms-sql-list-tables-and-database/
public static void main(String[] args) {
String[] str = new String[] {"cmd.exe", "/c", "sqlcmd -U abc -P abc -q sp_databases"};
Runtime rt = Runtime.getRuntime();
try{
String ss = null;
Process p = rt.exec(str);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
//obj.exec(ss);
System.out.println("Here is the standard output of the command:\n");
while ((ss = stdInput.readLine()) != null) {
System.out.println(ss);
}
System.out.println("Here is the standard error of the command (if any):\n");
while ((ss = stdError.readLine()) != null) {
System.out.println(ss);
}
}catch( Exception ex )
{
ex.printStackTrace();
}
}

Categories

Resources