Java - Open SSH client and send command - java

I'm building an app that needed to open a new SSH connection for the user, and then send automatically a command.
The app need to run on Windows, i thought about using putty to the SSH client and then send the command but the command don't sent to putty.
Anyone have any idea how can i implement this?
This is my code:
String command = puttyPath + " -ssh user#localhost"
process = Runtime.getRuntime().exec(command);
OutputStream out = process.getOutputStream();
Writer writer = new OutputStreamWriter(out);
writer.write(secondCommand);
writer.flush();
process.waitFor(600_000, TimeUnit.SECONDS);
Is there any possible to send only one command to putty and the putty will know to send it to the remote server?

PuTTY is a GUI application. Do not try to automate it.
Use the Plink instead. It's a console application from PuTTY package.
It supports input streams, what you code attempts to use. And also it allows support specifying the command on its command line:
String command = plinkPath + " -ssh user#localhost " + secondCommand;
Though even that is not the correct approach. Use some native Java SSH library, like the JSch, instead of using an external application.
See the JSch Exec.java example.

You can try to add for your command the "-m" and a file with secondCommand.
For more read about enter link description here

Related

Shell script working fine on linux system but not running on windows machine

I am running a java project on windows machine which reads shell script file for getting the authorization token but getting following error :
java.io.IOException: Cannot run program "./token.sh": CreateProcess error=193, %1 is not a valid Win32 application
Java program for reading the shell script:
private static String execCommand(String username){
String line;
Process p = Runtime.getRuntime().exec("./token.sh -u " + username + " -p password123");
BufferedReader input = new BufferedReader(new
InputStreamReader(p.getInputStream()));
StringBuilder output = new StringBuilder();
while ((line = input.readLine()) != null) {
output.append(line);
}
How can i run the same code on windows machine.
It will not. You see the commands used in Windows CMD and Shell are different since they are completely different platforms. Even-though you use java to execute, it will not execute due to underlying fundamental difference. It is quite clear from the exception you are getting.
What can you do?
Read through the token.sh. Most probably the internal implementation
can be implemented in Windows. Then create an if condition which
checks System.getProperty("os.name") Then if its windows then
call the bat file and if the OS is unix based call the sh file. For
every other OS throw a valid exception.
Other probable way is that, if the token generated in machine
independent, you can use SSH(JSch or similar) to remote connect to a
UNIX server and get the token. If the token is machine dependent (if
its an auth token, then probably is), try using Cygwin interpreter
,which itself does not assure you the every shell file will run in
it.
Change the sh file and its implementation to python or ruby.Then respective interpreter may be installed on machines (which it might actually have,except for production machines).
Write the sh logic in Java itself rather than keeping a script file, since platform independence is actually a requirement here and you already has JRE up and running in both machines.
You cannot do that since the commands that the Linux bash script requires is a lot different than the windows commands.
For example -
To list the contents in a directory in Linux ls
To list the contents in a directory in Windows dir
You have to write a machine/architecture/OS independent code to run across all the operating systems.
Maybe, you can try using Python scripting for that.
Or else, you can ssh from windows machine to Linux machine and run that script from windows in Linux server.
You have to make a Windows specific implementation as well of this script. The most common and easy approach would be to use powershell.
If you want a version that works on both Windows and Unix, perhaps you should look into python.

Executing the Unix script from Java

I am trying to run a unix shell script from java which is available at a particular directory in unix server. This script accepts parameters. I was able to establish SFTP connection and successfully reached to the directory which is holding the shell script. How do i run this script and how to pass parameters? Got few references at https://netjs.blogspot.com/2016/10/how-to-run-shell-script-from-java-program.html
but here the script is available at local system. In my case the script is on server and also accepts parameters.
SFTP is a file transfer protocol (Secure File Transfer Protocol). It lets you transfer the files to and from the server. However, it doesn't let you execute any script on the remote server as that's not what it's designed to do.
If you want to execute a script in remote server then you need to:
Establish an ssh connection
Execute the script from that connection
You need to use a library like JSch, here's an example.
Another way is execute command over SSH.
You create a new script in your localhost (my sample is test.sh) with content as below, and now you can execute it like the way you get from your references.
ssh user#server "sh your-shell-script-in-server.sh"
Read more at
https://www.cyberciti.biz/faq/unix-linux-execute-command-using-ssh/
Java source:
String[] cmd = new String[] { "/bin/sh", "test.sh" };
try {
Process pr = Runtime.getRuntime().exec(cmd);
int rs = pr.waitFor();
} catch (IOException | InterruptedException e) {
e.printStackTrace();
}
Your Java function is based on the Runtime object. I'm not sure but I think you can't get the Runtime object of a remote machine, therefore you'll need to put the CLASS-file on that remote machine and launch it up there.

Run jarfile on ftp without downloading

I have executable jar file which i have kept on my ftp.
I wanted to autoschedule it through linux server - cronjob.
I given the command :
java -jar filepath.jar
But when call goes to that file, it always asks for download, and after getting downloaded, it does not run automatically.
I want it to run automatically on the same server on which it is present (on ftp).
which command i can use for it??
Please help.
You could put something like this in your crontab :
ssh user#host 'java -jar filepath.jar'
and previously exchanging public keys between client and server so you won't be asked for the password
FTP is file transfer protocol. It cannot be used to execute programs. You have to use ssh, if that is possible.
Yes, use ssh to login into remote PC or server ,
That can be done using command "ssh username#IP Address of remote pc" on terminal.
By this way u can login in into remote pc and u will get the terminal of that PC inside your terminal.
Now u can browse the files in that PC and simply execute any file u want without downloading.

Executing screen command from Java

I am using the following code to execute an SH file in Linux
Runtime.getRuntime().exec(new String[] { "/bin/sh", "-c", file.getPath() });
This code works however I can't use the screen command in the SH file when executing it from Java, I get this error
Must be connected to a terminal.
So is it possible to "connect" java to a terminal? I would like to be able to also view this screen when I connect via SSH so I think it has to be connected to the terminal that is shown when you SSH into the server.
I found that if I use screen -dm it will work. Thanks!

Java Runtime.exec() with ssh on Linux Issues

I am trying to start a new process using Runtime.exec(), but my problem lies within using ssh to remote in and then run a java program there. Code:
test = "ssh -t username#host java packageName.ClassName portNumber (Other command line args for this class)"
Process proc = Runtime.getRuntime().exec(new String[] {"/bin/bash", "-c", test});
this doesn't fail or catch, but I need to be able to see the stdout for the newly running process and I don't.
Note: if I run ssh -t username#host java packageName.ClassName portNumber (Other command line args for this class) from the command line it works fine. I have the host setup to not require a password by using ssh keys.
Any ideas?
You need to use Process.getInputStream to obtain the output from the sub-process being created.
See this article for a good discussion on Runtime.exec.
I think you can ask for an input stream that corresponds to the stdout of the process and then print it on your standard output. If you need to see it after it executes, just call waitFor() method on the process so it finishes before you start printing.
Use getInputStream() to access returned process's stdout. You can also use facilities provided by ProcessBuilder.Redirect.

Categories