How to open a command terminal in Linux? - java

I want to open the terminal (command prompt) on a Linux machine using Java code.
I know how to open command prompt in windows.The following code i have used in windows
String command= "cmd c/start cmd.exe"
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
I need the same thing in Linux.
Thanks for your answers. I would like to run a sh script also.
Whether the following code works.
String command= "usr/bin/xterm myshell.sh";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);

In Linux, there are a number of terminal emulators which allow you to interact with various shells. Each shell is basically a command interpreter that understands Linux commands (GNU & Unix commands is more correct I suppose...). A terminal emulator provides an interface (window) for the shell and some other facilities for using the command prompt. To open a terminal window, you just have to modify your command string like this:-
import java.io.*;
class TerminalLauncher
{
public static void main(String args[]) throws IOException
{
String command= "/usr/bin/xterm";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
}
}
The basic assumption I have made is that you want to open xterm, which is available on almost any system (with X installed of course). You might want to open another terminal emulator like rxvt, eterm, aterm, gnome-terminal or konsole. The command string can also be modified to use different shells like zsh. I suggest you catch an exception in case the terminal you chose isn't present and handle it by asking the user to install it. A better solution is to accept command line arguments for the users preferred shell or to use a configuration file which the user can change to make your script open the shell of his/her choice.
Note
1. As others have already pointed out, xterm (or any other terminal of your choice) may not be in the path specified (/usr/bin/...) and may not even be installed, so you might have to use some fancy command string (Ex: pipelining find through grep to get the path to xterm before launching), which isn't such a great idea. I think the best way is to let the user configure the whole thing.
2.I got a comment on this answer (by ypnos), suggesting that I avoid using absolute paths and rather rely on the command being in the PATH environment variable. I have to say I agree. In that case, the command string should be -
String command = "xterm"
Do look at the comment, because it also points out the problem with using find.

There's no single standard "terminal" command on Linux - the ones available depend on which GUI is present (i.e. whether KDE, or Gnome, etc).
You should be able to rely on xterm being present, but on modern Linux variants that's not the terminal of choice:
String command= "/usr/bin/xterm";
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);
Of course, "xterm" might not be in that particular path...

Under Gnome, it's gnome-terminal.
Under KDE, it's konsole.
Or you could use the more generic terminal program xterm.
You'll probably want to use options with most of this, so look up the man pages for the one you want.

xterm will most probably be available on most Linux-based operating systems and if present will be found in the path variable.
Therefore, you will need to do something like this:
try {
Runtime r = Runtime.getRuntime();
String myScript = .....
String[] cmdArray = {"xterm", "-e", myScript + " ; le_exec"};
r.exec(cmdArray).waitFor();
} catch (InterruptedException ex){
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
The -e option can be used to invoke either a script or another program, for example: javac. In this case you would make an assignment like: myScript = "javac".
You will need the " ; le_exec" part if you do not want the window to immediately close after execution, otherwise discard it. The semi-colon is used to separate commands and le_exec is just a simple script that waits for the user to press Enter.
However, if your script needs arguments, then you would need to replace the String myScript by and array of Strings.

I think it would be nice if your application will open user's default terminal application.
Unfortunately, it seems that there is no universal way to determine it.
In my opinion the most preferrable solution would be (stop whenever you can open something):
try to recongnize user's desktop environment and determine it's default terminal application. You can read something about it here.
check environment variable $TERM
Ask user for her preference and save it in configuration file.
Finding out user's desktop environment and it's default terminal might be too complicated for your purpose, so I'd use two last options.
You can run application from $TERM with code like this:
String command = System.getenv().get("TERM");
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command);

There isn't actually a "the" terminal. What you really want is shell. Most Linuxes uses BaSH as a shell, but to keep on the safe side you should restrict yourself to /bin/sh
Edit: Hmm I probably missunderstood the question. If you want an interactive terminal you should look into using a toolkit providing a component for that.
Edit2: Maybe your needs can be served by VTE which is a GTK+ component for embedding a terminal.

I would definitely provide an easy way to configure the path to the desired terminal in a place that can be easily edited. For example maybe in a configuration XML file.
Different distros will keep this in different places, so it's probably best to check the per distribution documentation for the platforms you're targeting (and to document how to change it).
"/usr/bin/xterm" should be on most machines, but I wouldn't necessarily bet the farm on it.

since you have to assume you know almost nothing about the system you are running this on, I'd say lowest common denominator would be:
String command= "/bin/sh";
or even more 'guaranteed' -
String command= "sh";

Related

how to detect the terminal running the JVM within the java Application

I am creating a little CLI java application.
I have some trouble to manage a consistent clear screen functionality on Windows.
All solutions I have found are based on detecting the operating system.
Something like:
System.getProperty("os.name").indexOf("win") >= 0
and apply one of the documented Java: Clear the console answer depending whether it is Windows or not.
The disadvantage of this approach is that the clear screen is not working the same way if you run your java application in a cmd, git-bash or a Cygwin terminal. You cannot apply the cmd clear screen inside git-bash and the other way arround.
Based on that I would prefer to detect the terminal I am running on.
I thought to check if a Linux specific command would fail using a ProcessBuilder as a way to detect that I am in a cmd terminal but all the one I could think of also exists in a cmd terminals: ls, grep, awk. It is maybe because I have a WSL (Windows Linux Subsystem) installed but I am not sure.
Is there a way to detect the terminal running the JVM?
A simple way to achieve this is to introspect the environment variables of a system process.
You can achieve this with ProcessBuilder by checking if the PS1 environment variable is defined.
This is the variable I found, it is maybe not completely robust and could be present in your Windows environment. In that case find an other one in the collection returned by ProcessBuilder.environment().
ProcessBuilder pb = new ProcessBuilder();
if(pb.environment().containsKey("PS1")) {
System.out.println("non Windows console");
} else {
System.out.println("Windows console");
}

Trying to rename a computer OR execute a .bat file in Java

I'm trying to write a script to rename a computer (among other things) but just can't seem to figure it out. I don't really care what method I use to change the computer as long as i can change it. I found out how to read the computer name by doing
String computername = InetAddress.getLocalHost().getHostName();
However, that doesn't seem to offer any help in setting the computer name. Is there a way to set the Computer Name directly in the java console?
If not, or if anyone has better experience in this area, I also wrote a script using powershell 2.0 that renames the computer. I'm trying to figure out how to run that using
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("file location");
I followed the guide here but when trying to run a test .bat file that should just open the command line I just get this output in the java console:
C:\Users\Stephen\Desktop\opencmd.bat is found
OUTPUT>
OUTPUT>C:\Users\Stephen\workspace\UNM computer rename>cmd.exe
OUTPUT>Microsoft Windows [Version 6.1.7601]
OUTPUT>Copyright (c) 2009 Microsoft Corporation. All rights reserved.
OUTPUT>
It looks like it's just spitting back the command line output into the java console, instead of just running the command and opening the cmd line.
I would really appreciate input as I'm in a crunch for time here, thanks!
First, JDK really does not provide pure java API that allows changing computer name. So you have to run script.
Second, if you want to run script using Runtime you have to provide correct command line. So first try to run your script manually. I believe it accepts a least one parameter (the new computer name). So run it from command prompt and see it is working. Then put it to the working directory of your java program and copy/paste the command line into the java code and see that it is working now. if you want you can read STDOUT of your script and/or get its return code. If you do not care about its output just call process.waitFor() and then get the return code.
Be careful with arguments. Windows computer name may contain unicode characters and spaces. If it contains spaces surround it with quotes. Concerning unicode just try. I hope it will not cause problems to you.
You can also use ProcessBuilder class that allows better and more portable arguments passing.
Good luck.
It looks like opencmd.bat is being executed, so assuming your PowerShell script works, is it possible you don't have administrative privileges?
You can also do it elegantly using JNA, I think this would be the target. But if you are rushed for time, don't bother.

Java ProcessBuilder showing console of started java application?

I have a JAVA application that launches (using ProcessBuilder) another JAVA application like this:
String val = "something";
ProcessBuilder processBuilder = new ProcessBuilder("java", "-classpath", dir, appName, val);
Process p = processBuilder.start();
Now, this works fine, appName is launched with the parameter val and it runs and works ... great ... the problem is no Console Window appears ... appName does a LOT of outputting to the console and we need to see it ... how can I start the process with a console?
I am trying stuff like ("CMD.exe", "java", "-classpath", dir, appName, val), etc... but I can't get it right ...
Also, I can't redirect the streams, my program can actually start 5-10 of these appName's, each should have their own console window showing their own information.
Any help would be much appreciated.
Thanks,
console windows are generally not the most reliable form of logging. they only store a set amount of information (buffer) and can behave differently across platforms.
i strongly suggest logging to a file using something like log4j and if you need to see it real time use a tail like program (i see you're using windows).
in addition to this, seeing as you want the windows visible at all times and launching a tail program for each log might be annoying, i'd write my own log window in java swing.
the basic idea is to not rely on the OS too much.
Tried Runtime.getRuntime().exec("cscript java -classpath ..."); ?
Anyway, consider using a logging framwork (log4j, commons-logging), because opening 5 consoles is not the most clever thing to do.
I call a few shell scripts via Process to open a command line window and launch whatever I need. As long as the scripts don't detach - you can usually stop any shell command from doing this -java will still hold the running process.
I did it in linux but the concept should be similar.
#!/bin/bash
# To open a process in a new window.
gnome-terminal -x ./your-real-shell-script-here.sh "$#"
the real script will have your java execution in it, such as:
#!/bin/bash
java -jar your-jar-file.jar "$#"
I think you can use javaw to run on windows, so you might only need the one shell script.
A Console object only exists when you execute java.... from a console. Otherwise, the call to obtain one returns null.
If you want to see a console, you need to open a command shell console (e.g. windows cmd.exe or Unix bash shell window) and type:
java -classpath="..." com.example.appName arg1
If you want to run in a different manner, sorry to say, logging to Console is not for you. Instead, log using one of:
log4j
slf4j
logback

Java : how to determine disk space on Windows system prior to 1.6

I want to determine the available disk space on windows. I don't care that my code is not portable. I use this :
String[] command = {"dir",drive};
Process process = Runtime.getRuntime().exec(command);
InputStream result = process.getInputStream();
aiming to parse the result from a "dir C:" type of call, but the String I get from the command line call is as if I called dir with a /W option (not giving any information about file sizes or disk usage / free space). (Although when I launch dir C: directly from the command line, I get the expected result, so there is no dir particular setup on my system.) Trying to pass a token /-W or on any other option seems not to work : I just get the name of the folders/files contained in the drive, but no other information whatsoever.
Someone knows a fix / workaround ?
NOTE:
I can't go along the fsutil route, because fsutil does not work on network drives.
It sounds like your exec() is finding a program called "dir" somewhere in your path because with your String[] command as it is I would otherwise expect you to get an IOException (The system cannot find the file specified). The standard dir command is built into the cmd.exe Command Prompt and is not a standalone program you can execute in its own right.
To run the dir command built into cmd.exe you need to use the /c switch on cmd.exe which executes the specified command and then exits. So if you want to execute:
cmd /c dir
your arguments to pass to exec would be:
String[] command = { "cmd", "/c", "dir", drive };
If you don't care about portability, use the GetDiskFreeSpaceEx method from Win32 API. Wrap it using JNI, and viola!
Your Java code should look like:
public native long getFreeSpace(String driveName);
and the rest can be done through the example here. I think that while JNI has its performance problems, it is less likely to cause the amount of pain you'll endure by using the Process class....
Apache Commons has FileSystemUtils.freeSpaceKb() that will work cross platfrom etc etc

Launching jEdit From Java Swing App Using Runtime.getRuntime().exec()

I'm writing a Java Swing Application running on Red Hat Enterprise Linux 5 server that I would like to launch jEdit to view log files.
Here is some example code.
public static void main(String[] args) throws IOException, InterruptedException {
String cmd = "sh -c \"java -jar /tmp/jEdit/jedit.jar /tmp/test.txt\"";
System.out.println(cmd);
Runtime.getRuntime().exec(cmd);
}
The output is:
sh -c "java -jar /tmp/jEdit/jedit.jar /tmp/test.txt"
If I copy and paste the cmd output in a terminal window, it runs fine.
I have tried a bunch of cmd values, but I can never get the jEdit window to be visible.
With changes, this process works fine on Windows.
Is what I'm doing possible on Linux?
Thanks in advance!
As jEdit is implemented in Java, perhaps it would be easier to check the source for what the main method (in the class declared in the manifest file included in the jedit.jar) does and do the same thing without using Runtime.getRuntime().exec() at all.
If you do want to stick with it, you could try passing the individual commands as an array to exec(), this often solved such problems for me.
Linux uses the concept of display ports for its X-Windows system. This allows it to maintain a different desktop environment for each user. It also allows a user on remote machine to run a desktop app from the first machine but see the UI on the remote.
Windows, having only one available desktop environment at a time, does not.
First thing you definitely have to do is add the environment variable "DISPLAY=localhost:0" to the environment from which you are launching this. However, you may also need to run 'xhost +localhost' or this may not be allowed.
Double-check, too, that you didn't successfully launch a bunch of jEdit processes that are now zombies (using top) and kill them if necessary (using kill).
Runtime.exec() needs some special attention. The exec method that accepts a String uses the space character as a delimiter to break up the string into commands. You need to use the exec method that accepts a String[]. Read more here, specifically near the bottom.
I´ve done this once and I got the same problem
What I've done is to write the command line into a text file and then execute the text file as a shell script file.
It worked fine for me.
Jedit has a launcher script, /usr/bin/jedit I guess. Simply typing jedit in command prompt runs it, at least in current version, 4.5. Try that script instead of explicit java command.

Categories

Resources