I want to automatically change the ip address of an Ubuntu 12.04 PC by a program fires at startup. For some certain reasons, I want to code it in Java.
Exactly the solution is written here:
Java - Execute a .SH file
But it does not work in my case. I could not manage to find why,essentially my case is a special case of so called thread, I try to run a sudo-command in linux with
public static void executeCommandLine(String strCommand){
Runtime rt = Runtime.getRuntime();
try {
Process p = rt.exec(strCommand);
if(p==null){
System.out.println("Error in process");
}
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
try {
while ((line = reader.readLine()) != null)
{
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
}
I call this executeCommandLine() function from another function as follows:
public static void changeIpAddress(String strIpAddress, String strRootPassword, String strEthDevice){
String strCommandLine = "";
if(PLATFORM == PLATFORM_LINUX){
strCommandLine = "/bin/echo " + strRootPassword + "| sudo -S /sbin/ifconfig " + strEthDevice + " " + strIpAddress;
}else if(PLATFORM == PLATFORM_WINDOWS){
// TODO: Write for Windows
}else{
System.out.println("OS not supported");
}
System.out.println("Executed command:");
System.out.println(strCommandLine);
executeCommandLine(strCommandLine);
}
Related
I need my Java program to immediately stop if my VPN disconnects. I understand I can periodically run a command and parse the output, but this seems inefficient. I'm assuming it's possible to setup a receiver/listener instead but all the solutions I come across are Android oriented. Any recommendations?
Here's my approach (run every n seconds):
public boolean isConnected() {
boolean isConnected = false;
try {
Process p = Runtime.getRuntime().exec("cmd.exe /c netsh interface show interface");
BufferedReader stdin = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line;
while ((line = stdin.readLine()) != null) {
if (line.contains("Ethernet 2")) {
List<String> valueList = Arrays.asList(line.split("[\\s]{2,}"));
String connectedOrDisconnected = valueList.get(valueList.indexOf("Ethernet 2") - 2);
System.out.println("connectedOrDisconnected: " + connectedOrDisconnected);
isConnected = Objects.equals(connectedOrDisconnected, "Connected");
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
return isConnected;
}
While trying to run a simple HelloWorld Unix executable:
#include <iostream>
using namespace std;
int main() {
cout << "Hello World!" << endl;
}
(Compiled through g++ HelloWorld.cpp -o HelloWorld (on Mac). The program works on my Mac by using ./HelloWorld and by letting it run through a Java environment:
(HelloWorld.java -> working)
public class HelloWorld
{
public static void main(String args[])
{
String[] command = new String[]{"/system/bin/chmod", "744",
"/Developer/Java/HelloWorld" };
execute(command);
command = new String[]{"./HelloWorld"};
execute(command);
}
public static void execute(String...command)
{
StringBuilder log = new StringBuilder();
try
{
BufferedReader br;
String line;
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process proc = builder.start();
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ( (line = br.readLine()) != null)
System.out.println(line + "\n");
}
catch (IOException e) {
log.append("General IOException:\n" + e.getMessage() + "\n");
}
catch (InterruptedException e) {
log.append("Error:\n" + e.getMessage() + "\n");
}
}
}
In my java code for the Android app, I first copied the executable to getBaseContext().getDataDir(), this works fine. To change the permissions I'm using the following:
command = new String[]{"/system/bin/chmod", "744",
getAssetsPath() + "/HelloWorld" };
execute(pv, command);
and trying to run the program through:
command = new String[]{"." + getAssetsPath() + "/HelloWorld"};
terminal(tv, command);
Note, that I use the following functions:
public File getAssetsDir() {
return getBaseContext().getDataDir();
}
public String getAssetsPath() {
return getAssetsDir().getAbsolutePath();
}
public void execute(TextView tv, String...command)
{
tv.setText("Starting Terminal.\n");
StringBuilder log = new StringBuilder();
try
{
BufferedReader br;
String line;
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process proc = builder.start();
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
while ( (line = br.readLine()) != null)
log.append(line + "\n");
}
catch (IOException e) {
log.append("General IOException:\n" + e.getMessage() + "\n");
}
catch (InterruptedException e) {
log.append("Error:\n" + e.getMessage() + "\n");
}
tv.setText(log.toString());
}
As already said this will result in the following error inside the TextView (tested on Pixel_XL_API_25):
syntax error: '__TEXT' unexpected
Hope you can help me find the cause of this problem. Thanks in advance.
Edit:
If you want to know why I want to use a Unix executable for such simple things: This is just for testing. Actually, I want to run other more complex programs/libraries which will be hard to use through ndk, because there is no cmake for this library, only "normal" make.
The answer is, that the compiler isn't the right compiler to use. If you want to run it on another device you have ti compile it there or use some cross compiler, I guess.
The question is now: Which compiler would work? I found this suggestion (How to compile and run a C/C++ program on the Android system):
arm-linux-gnueabi-g++ -static -march=armv7-a HelloWorld.c -o HelloWorld
But that won't work in this specific constellation.
I have a SQL script which I would like to execute from a Java class, running on Windows. I am currently trying to do this using ProcessBuilder in the following function:
public static boolean runSqlScript(String filename, String user, String password) {
ProcessBuilder pb = new ProcessBuilder("mysql", "-u"+user, "-p"+password, "< "+ filename);
try {
Process pr = pb.start();
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
The filename is the absolute path to the script, and the user and password are verified correct. But when I run this, I get the error:
ERROR 1102 (42000): Incorrect database name '< c:/path/to/script.sql'
Why is it interpreting that as a database name rather than a command line argument? Can I use ProcessBuilder to run the script like this?
You need to add database name and it will work ProcessBuilder pb =
new ProcessBuilder("cmd", "/c", "mysql", "-u"+user, "-p"+password,"dbname", " < "+ filename);
Runtime.exec() can also be used to send commands, which doesn't seem to have the same issue as ProcessBuilder:
public static boolean runSqlScriptRuntime(String filename, String user, String password) {
Runtime rt = Runtime.getRuntime();
try {
String cmd = "cmd /c mysql -u " + user + " -p" + password + " < " + filename;
System.out.println(cmd);
Process pr = rt.exec(cmd);
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
An alternative to trying to simulate command-line arguments is to call the SQL script from inside mysql, as described here.
public static boolean runSqlScript(String filename, String user, String password) {
ProcessBuilder pb = new ProcessBuilder("mysql", "-u"+user, "-p"+password);
try {
Process pr = pb.start();
BufferedReader errors = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
BufferedReader output = new BufferedReader(new InputStreamReader(pr.getInputStream()));
BufferedWriter input = new BufferedWriter(new OutputStreamWriter(pr.getOutputStream()));
input.write("source " + filename + ";");
input.flush();
input.write("quit;");
input.flush();
input.close();
while (pr.isAlive()) {
try {
System.err.println(errors.readLine());
System.out.println(output.readLine());
Thread.sleep(10);
} catch (InterruptedException e) {
break;
}
}
System.err.println(errors.readLine());
System.out.println(output.readLine());
int status = pr.exitValue();
return (status == 0);
} catch (IOException e) {
System.err.println("Error running command: " + e.getMessage());
return false;
}
}
This will run MySQL and then call the script. However, I originally was using ProcessBuilder because I thought the script could be handled in a single command line - with a solution like this, it probably makes more sense to just use JDBC.
I want to test to run mysqldump command in my function but I could not create aaadumpdb.sql file. My code is below:
#Test
public void dumpDB() {
Process p = null;
try {
Runtime runtime = Runtime.getRuntime();
p = runtime
.exec("mysqldump -u root -padmin --add-drop-database aaa_db "
+ "D:\\backupdenemeaaa " + "aaadumpdb.sql");
// change the dbpass and dbname with your dbpass and dbname
int processComplete = p.waitFor();
if (processComplete == 0) {
System.out.println("Backup created successfully!");
} else {
JOptionPane.showMessageDialog(new JDialog(),
"Could not create the backup");
}
} catch (Exception e) {
e.printStackTrace();
}
File f = new File("aaadumpdb.sql");
assertTrue(f.exists());
}
Can anybody give me some advice about it? Thank you.
I did some edit in my code but when I run, my code enter into else structure. What can be the problem?
My editted code is below:
#Test
public void dumpDB() {
Process p = null;
try {
Runtime runtime = Runtime.getRuntime();
String mysqldumpExecutable = "C:\\Program Files\\MySQL\\MySQL Server 5.6\\bin\\mysqldump.exe";
p = runtime.exec(mysqldumpExecutable + " -uroot -padmin --add-drop-database -B aaa_db -r" + "D:\\backupdenemeaaa " + "\\aaadumpdb.sql");
// change the dbpass and dbname with your dbpass and dbname
int processComplete = p.waitFor();
if (processComplete == 0) {
System.out.println("Backup created successfully!");
} else {
JOptionPane.showMessageDialog(new JDialog(),
"Could not create the backup");
}
} catch (Exception e) {
e.printStackTrace();
}
File f = new File("aaadumpdb.sql");
assertTrue(f.exists());
How can I solve this problem? Thank you.
The stacktrace would really help to debug it, but I believe you can check if "mysqldump" is in your PATH or the application will simple not find the executable. If you don't want to mess around with your PATH you can hardcode the path to the executable like below:
String mysqldumpExecutable = "C:\\apps\\mysql\\mysqldump.exe";
runtime.exec(mysqldumpExecutable + "-u root -padmin --add-drop-database aaa_db (.....));
When you say you can't create the file what exactly does that mean? Are you getting an error? Nothing happens? Help us help you.
Add the below snippet to find what exactly is happening
try
{
InputStreamReader isr = new InputStreamReader(process.getErrorStream());
BufferedReader br = new BufferedReader(isr,4094);
String line=null;
while ( (line = br.readLine()) != null)
System.out.println(type + "> " + line);
} catch (IOException ioe)
{
ioe.printStackTrace();
}
}
You will be aware of the the exceptions and errors that might occur in that Process execution
This might be an easy one - but it's driving me nuts at this point. I'm trying to run SoX from Processing which on my mac computer is running smoothly and with no problems. I need to migrate the code to a windows 7 machine but can't get it to work for some reason. Talking to the terminal from processing works fine. I'm in the right folder (sketch data folder where SoX is also intalled) since I can run commands like "dir" etc. and get the right content printed - but as soon as I try to run sox.exe nothing happens (getting an exit value 1). Running sox.exe straight from the cmd terminal works fine. Here is a sample of what I'm trying to do:
void playBackYear (){
soxPlay = "cmd /c sox.exe year.wav -d";
println (soxPlay);
try {
File workingDir = new File(sketchPath("data"));
Process p=Runtime.getRuntime().exec(soxPlay, null, workingDir);
p.waitFor();
BufferedReader reader=new BufferedReader(
new InputStreamReader(p.getInputStream())
);
String line;
while ( (line = reader.readLine ()) != null)
{
println(line);
}
int exitVal = p.waitFor();
System.out.println("Exited with error code "+exitVal);
}
catch(IOException e1) {
System.err.println("Caught IOException: " + e1.getMessage());
System.out.println( "error 1" );
}
catch(InterruptedException e2) {
System.err.println("Caught IOException: " + e2.getMessage());
System.out.println( "error 2" );
}
}
So the questions is what am I doing wrong here?
Any help is appreciated.
I have written a small wrapper application that wraps sox binary in java. If you are interested in the full project, check it out on GitHub: sox java wrapper project
This is, how i have solved the problem:
private List<String> arguments = new ArrayList<String>();
// add sox arguments to this list above
public void execute() throws IOException {
File soxBinary = new File(soXBinaryPath);
if (!soxBinary.exists()) {
throw new FileNotFoundException("Sox binary is not available under the following path: " + soXBinaryPath);
}
arguments.add(0, soXBinaryPath);
logger.debug("Sox arguments: {}", arguments);
ProcessBuilder processBuilder = new ProcessBuilder(arguments);
processBuilder.redirectErrorStream(true);
Process process = null;
IOException errorDuringExecution = null;
try {
process = processBuilder.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = reader.readLine()) != null) {
logger.debug(line);
}
} catch (IOException e) {
errorDuringExecution = e;
logger.error("Error while running Sox. {}", e.getMessage());
} finally {
arguments.clear();
if (process != null) {
process.destroy();
}
if (errorDuringExecution != null) {
throw errorDuringExecution;
}
}
}