How to call the linux command "source FILE_NAME" from Java? - java

Actually I have two commands :
source FILE_NAME
Install ABCD
Before executing the second command, i need to execute the first one. I tied to execute both the command using Runtime.getRuntime().exec(cmd) methos, but second command failed, since it depends on the first one. I tried many combinations, but not succeeded. Can anybody please help me?

You're probably executing two separate exec commands, spawning separate processes, and so whatever you do in the first process is not visible to the second. Resolve this by putting all of your commands into a script (bash, ksh, etc) and call it once from your Java program.
Paramterize your script so you can pass arguments.
Here's some help on writing your first shell script
[Edit] As mentioned by #RNJ you can look at using ProcessBuilder to pass in environment variables to each of the processes spawned. This will be fine if you can specify the name of the file being created ahead of time. Example code taken from the API link above...
ProcessBuilder pb = new ProcessBuilder("myCommand", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
Process p = pb.start();

Related

Executing commands with the ProcessBuilder in java

I want to run the following command from a java file command : "java hello < C:\iptest\input.txt > C:\outtest\name.txt "hello" will take input from "C:\iptest\input.txt" and will produce an output file at "C:\outtest\name.txt".
codes i have done
String command[]={"java","hello","< C:\\iptest\\input.txt >","C:\outtest\name.txt"};
ProcessBuilder pb=new ProcessBuilder(command);
pb.directory(new File("E:\"));
and now how to go forward i have no idea .Please Help!!
Here is a link to the ProcessBuilder definition on Oracle, which explains how to use this class. Typically, this is used for executing non-java processes, e.g. .BAT or .EXE processes, but I suppose you could use it to execute any process you wish.
http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html

Change PWD of linux from JSP

I need to execute linux commands from JSP.
It is working fine.
But i need to start some sh file in a particular directory in linux through JSP. say /home/username/something/start.sh
try{
String command= "cd /home/username/something";
Runtime.getRuntime().exec(command);
Runtime.getRuntime().exec("./start.sh")
out.println("Child");
}
catch(Exception e)
{ out.println("Error");
}
It says FIle or Directory not found.
I tried Runtime.getRuntime().exec("pwd"), It is showing something like "java.lang.UNIXProcess#fc9d2b" !! :O
I need to change the pwd and execute some commands through jsp. How can i do that??
Any help would be appreciated.
You shouldn't (and actually, it seems you can't) set a working directory like that. Each Process object given by Runtime.exec() will have its own working directory.
As answered in How to use “cd” command using java runtime?, you should be using the three argument version of Runtime.exec(), in which you provide a File that will be the working directory. From its javadoc:
Executes the specified command and arguments in a separate process with the specified environment and working directory.
Or even better, use ProcessBuilder along with ProcessBuilder.directory() instead:
ProcessBuilder pb = new ProcessBuilder("start.sh");
pb.directory(new File("/home/username/something"));
Process p = pb.start();

How to run a script from Java

I have a script, which is test.sh on Ubuntu. I want to run it from Java. I know I have to use Runtime.getRuntime().exec();
Don't I have to fill the exec parenthesis with the location of test.sh? I am typing /home/main/ss/test.sh
I do not get any error messages but when I searched the folder, I saw that script did not work. How can I fix it?
You should really look at Process Builder. It is really built for this kind of thing.
ProcessBuilder pb = new ProcessBuilder("myshellScript.sh", "myArg1", "myArg2");
Map<String, String> env = pb.environment();
env.put("VAR1", "myValue");
env.remove("OTHERVAR");
env.put("VAR2", env.get("VAR1") + "suffix");
pb.directory(new File("myDir"));
Process p = pb.start();
Did you try to call your script directly, or did you specify a shell to use? You may need to specify the shell on your exec call if it's not specified (and processed) from the first line of the script.
From looking at your description, how you conclude the script didn't work:
I do not get any error messages but when I searched the folder, I saw
that script did not work. How can I fix it?
I conclude, the script creates a new file, and there is none, after starting from Java.
Maybe you assume, that the output of the script will, if sent to the current directory, end in the directory of the script, not in the directory where you started your Java application.
This might be the Desktop, if you start your class from the UI with an Icon as starter, it might be your home or project dir, if you compile the class from hand, or a directory, set up by your IDE, if you develop with eclipse or the like.
If your script writes to an absolute path like /tmp/script.out, you could verify fast, whether this might be your issue.

How to execute unix commands through Windows/cygwin using Java

I am trying to accomplish two things:
I am running cygwin on Windows7 to execute my unix shell commands and I need to automate the process by writing a Java app. I already know how to use the windows shell through Java using the 'Process class' and Runtime.getRuntime().exec("cmd /c dir"). I need to be able to do the same with unix commands: i.e.: ls -la and so forth. What should I look into?
Is there a way to remember a shell's state?
explanation: when I use: Runtime.getRuntime().exec("cmd /c dir"), I always get a listing of my home directory. If I do Runtime.getRuntime().exec("cmd /c cd <some-folder>") and then do Runtime.getRuntime().exec("cmd /c dir") again, I will still get the listing of my home folder. Is there a way to tell the process to remember its state, like a regular shell would?
It seems that the bash command line proposed by Paŭlo does not work:
C:\cygwin\bin>bash -c ls -la
-la: ls: command not found
I am having trouble figuring out the technicalities.
This is my code:
p = Runtime.getRuntime().exec("C:\\cygwin\\bin\\bash.exe -c ls -la");
reader2 = new BufferedReader(new InputStreamReader(p.getInputStream()));
line = reader2.readLine();
line ends up having a null value.
I added this to my .bash_profile:
#BASH
export BASH_HOME=/cygdrive/c/cygwin
export PATH=$BASH_HOME/bin:$PATH
I added the following as well:
System Properties -> advanced -> Environment variables -> user variebales -> variable: BASH, value: c:\cygwin\bin
Still nothing...
However, if I execute this instead, it works!
p = Runtime.getRuntime().exec("c:\\cygwin\\bin\\ls -la ~/\"Eclipse_Workspace/RenameScript/files copy\"");
1. Calling unix commands:
You simply need to call your unix shell (e.g. the bash delivered with cygwin) instead of cmd.
bash -c "ls -la"
should do. Of course, if your command is an external program, you could simply call it directly:
ls -la
When starting this from Java, it is best to use the variant which takes a string array, as then
you don't have Java let it parse to see where the arguments start and stop:
Process p =
Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe",
"-c", "ls -la"},
new String[]{"PATH=/cygdrive/c/cygwin/bin"});
The error message in your example (ls: command not found) seems to show that your bash can't find the ls command. Maybe you need to put it into the PATH variable (see above for a way to do this from Java).
Maybe instead of /cygdrive/c/cygwin/bin, the right directory name would be /usr/bin.
(Everything is a bit complicated here by having to bridge between Unix and Windows
conventions everywhere.)
The simple ls command can be called like this:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\ls.exe", "-la"});
2. Invoking multiple commands:
There are basically two ways of invoking multiple commands in one shell:
passing them all at once to the shell; or
passing them interactively to the shell.
For the first way, simply give multiple commands as argument to the -c option, separated by ; or \n (a newline), like this:
bash -c "cd /bin/ ; ls -la"
or from Java (adapting the example above):
Process p =
Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe",
"-c", "cd /bin/; ls -la"},
new String[]{"PATH=/cygdrive/c/cygwin/bin"});
Here the shell will parse the command line as, and execute it as a script. If it contains multiple commands, they will all be executed, if the shell does not somehow exit before for some reason (like an exit command). (I'm not sure if the Windows cmd does work in a similar way. Please test and report.)
Instead of passing the bash (or cmd or whatever shell you are using) the commands on the
command line, you can pass them via the Process' input stream.
A shell started in "input mode" (e.g. one which got neither the -c option nor a shell script file argument) will read input from the stream, and interpret the first line as a command (or several ones).
Then it will execute this command. The command itself might read more input from the stream, if it wants.
Then the shell will read the next line, interpret it as a command, and execute.
(In some cases the shell has to read more than one line, for example for long strings or composed commands like if or loops.)
This will go on until either the end of the stream (e.g. stream.close() at your side) or executing an explicit exit command (or some other reasons to exit).
Here would be an example for this:
Process p = Runtime.getRuntime().exec(new String[]{"C:\\cygwin\\bin\\bash.exe", "-s"});
InputStream outStream = p.getInputStream(); // normal output of the shell
InputStream errStream = p.getInputStream(); // error output of the shell
// TODO: start separate threads to read these streams
PrintStream ps = new PrintStream(p.getOutputStream());
ps.println("cd /bin/");
ps.println("ls -la");
ps.println("exit");
ps.close();
You do not need cygwin here. There are several pure Java libraries implementing SSH protocol. Use them. BTW they will solve your second problem. You will open session and execute command withing the same session, so the shell state will be preserved automatically.
One example would be JSch.

How to run .reg file in Java

I need to install a .reg file (INTRANET) by using Java. How do i get my goal ?
Cheers,
You could use System.exec to launch regedit yourfile.reg
Here is how to do it :
String[] cmd = {"regedit", "yourfile.reg"};
Process p = Runtime.exec(cmd);
p.waitFor();
Last line is optional, it only allows you to wait until the operation is over.
If you're already on Java 1.6, just grab java.awt.Desktop:
Desktop.getDesktop().open(new File("c:/yourfile.reg"));
It will launch the file using the default application associated with it, as if you're doubleclicking the particular file in Windows explorer.
This can achieved through Process Builder in JAVA. Please consider the following example for this:
ProcessBuilder processBuilder = new ProcessBuilder("regedit", "reg_file_to_run.reg");
Process processToExecute = processBuilder.start();
And then you can optionally wait for the completion of process execution with this line:
processToExecute.waitFor();
Note: If command in your registry file asks for confirmation prompts while making changes in registry entries, you can perform it silently as well with '/s' option. Like this:
ProcessBuilder processBuilder = new ProcessBuilder("regedit", "/s", "reg_file_to_run.reg");
With this command would be executed silently without any confirmation prompt.

Categories