running ssh and executing commands on remote machines - java

I am a java developer and am assigned to work on a project in which I need to programmatically ssh into linux boxes and run some unix commands. After the commands have run, the output of the commands should be collected and displayed on the UI.
I saw a library called sshxcute which can be used to accomplish this. My questions are:
Is there a better solution than Java based for this kind of requirements like Nodejs or Ruby on Rails
Can get the real time logs from the system where the command is getting executed than getting the logs are the commands have been run.
Can run multiple parallel process on the machines asynchronously.

You can use sshj. It allows you to open a ssh connection, send commands and read the output.

I used jsch java library
ChannelShell channel = openShellChannel();
OutputStream outputStream = channel.getOutputStream();
PrintStream commander = new PrintStream(outputStream, true);
// Print logs
channel.setOutputStream(System.out, true);
// exec the command
commander.println(command);

Related

Running Unix command , after connecting through ftp using java

I am not authorized to use ssh/sftp( using private/public key). So ftp is my only choice.
The following piece of code works just fine for me, fetching the file from Unix box, but my motto is to log in to a UNIX box from windows, using java,then from my home directory go to a different directory and use grep, then copy that output back to my windows java program. I was looking for how to execute some Unix command in the box. as we do it in shell/python/ant...
new URL("ftp://user:password#url/sourcefile;type=i");
URLConnection con = url.openConnection();
BufferedInputStream in =
new BufferedInputStream(con.getInputStream());
FileOutputStream out =
new FileOutputStream("Targetfile");
If you have username and password then you can go for Jsch library.
Have a look at this or directly run it !!
http://www.jcraft.com/jsch/examples/Shell.java.html
Similarly you can all shell commands from this.
FTP is a file transfer protocol. It's not a general-purpose remote access protocol. It doesn't have built-in support for a client to run arbitrary commands on the FTP server.
FTP does have a command called SITE which permits running custom commands on the server. To use it, the FTP server's administrator would have to set up a custom command that meets your needs. Then you'd have to use a real FTP client library to invoke the site command on the remote server--calling openConnection() on an FTP URL won't let you invoke site commands.

how to access remote Linux machine through Java API

I need to access and run Linux commands on a remote CentOS machine through Java code. Please suggest me any API to access run the commands and also I need to get the output of the commands to be printed on the Java console.
Check out JSch - it allows you to connect via SSH, execute commands remotely and transfer files.
You can use Java ProcessorBuilder and Process classes to start an ssh process that executes remote command i.e. start an ssh process (e.g. ssh username#REMOTE_MACHINE 'CMD_ON_REMOTE_MACHINE') and read the output of the executed command using getInputStream() method of Process class.

Maintaining a SSH channel in Java with JSCH

I want to control a remote system in Java via SSH using JSCH.
The front end is a simple button GUI which triggers the execution of a command.
Some of the controls are time critical, there should be no big delay between button press and command execution.
My problem:
Every time a new channel is opened, the back-end needs about 8 seconds to initialize until the command is executed. (The back-end interface is implemented with RBSH afaik)
If I run a normal session via a console client, everything runs fine without bigger delays.
My question:
Is there a way to initialize a channel to execute some commands and read the output(and only the command output) back sequentially?
I already figured out that session.openChannel("shell") could give the desired functionality, but I cant figure out how to do that properly.
EDIT: I'm not tied to JSCH. If there's another library which can do that, I'm also open for that
You want an "exec" channel rather than a "shell" channel. SCP uses an exec channel, so look at one of the SCP examples or one of the SCP libraries on the Internet.
Alternately, if you control the remote server, you could define a "subsystem" for the command that you want to run, and run it through a subsystem channel. The big difference between an exec channel and a subsystem is who specifies the command to be executed. An exec channel will execute a command provided by the client. With a subsystem, the client just requests the subsystem by name, and the server runs the correct command (or provides the service in some other way). SFTP uses a subsystem called "sftp-server", so you could look at how Jsch's SFTP classes are implemented.

Operating terminal session from Java

I am trying to make a terminal emulator in Java. The java program will accept the commands from user, and show its output to them. I can emulate simple commands like 'ls', but I don't know how to handle commands like 'cd'. This is because, I am using exec() method for executing terminal commands. So, all the commands are executed at current directory. The commands like 'cd ..' are executed, but then they have no persistent effect, because each command is separately executed by exec().
Any Ideas How I can emulate a whole session??
If you are executing commands with exec(), you are not writing a terminal emulator; you are writing a shell. In that case, you will need to keep track of things the shell keeps track of, like environment variables and working directory.
If you really want to write a terminal emulator, you would be talking to a shell process through a pseudo-terminal. Then your program would just be keeping track of the things a terminal keeps track of, like the line state and what appears on the screen.
Working with a pseudo-terminal from Java will be a little tricky, because most of the documentation assumes you are using a C api. man pty should get you started. Your Java process will have to open the master side of the pseudo-terminal with FileStream objects. I'm not sure there is a way within Java to get a child process to open the slave side of the pseudo-terminal; you might have to invoke a shell command with exec() that starts another shell command with standard input/output/error redirected to the slave side of the pseudo terminal.
JSch is a pure Java implementation of SSH2.
JSch allows you to connect to an sshd server and use port forwarding, X11 forwarding, file transfer, etc., and you can integrate its functionality into your own Java programs.
http://www.jcraft.com/jsch/
You should really give a try to Ganymed.
Ganymed SSH-2 for Java is a library which implements the SSH-2
protocol in pure Java (tested on J2SE 1.4.2 and 5.0). It allows one to
connect to SSH servers from within Java programs. It supports SSH
sessions (remote command execution and shell access), local and remote
port forwarding, local stream forwarding, X11 forwarding, SCP and
SFTP.
http://www.ganymed.ethz.ch/ssh2/
Ganymed along with apache FTP client you can also download and upload files.
Also there is a inbuilt example code for terminal emulation in Ganymed.
The following is a link to a project which is did using Ganymed along with apache FTP client.
GITHUB
Happy Coding!!

How can I execute Linux commands on a remote machine using Java?

I have two secured linux servers. In one machine my Java application is running. I need to run Linux commands on second machine from first machine in Java. How might I do this?
Jsch (here) allows you to connect to a remote server using SSH and executes shell commands easily (and lot of other things like SCP, SFTP...). There is not a lot of documentation, but you have a few really helpful implementation examples here (and even an example of what you want to do here).
You can also combine Jsch with Expect4j and this way have a better control on the commands you want to execute (nice example here).
Essentially, you need to open an ssh connection to the other server from within your Java application. The OpenSSH site has some useful information on libraries that will give you ssh support in Java.
It looks like Ganymed SSH-2 for Java is the nicest of the pick there, but I haven't used any of them so you will need to look at what you need.
Once you have an ssh connection, you will be able to run commands just as if you logged in using any other ssh client.
You can do it a number of ways; however, nearly every way involves a network connection.
You could write a client-server pair of Java programs, with the client connection to a server and submitting the command.
You could write your Java to use an existing server, like sshd, telnetd, rsh, ftpd, or a pre-existing other server which allows commands at the remote end.
You could leverage an architecture which handles certain aspects of establishing a client-server pair, like RMI, SOAP, CORBA, etc.
In the end Java supports tons of networking options, so you have more ways of doing this than you think. Just make sure you don't do it in a web browser, as those JVMs are launched sandboxed, and you can't get out of the sandbox without some assistance.
It might be easier to check out Sockets, as you can do what you're trying to do without having to get any external libraries set up.
On the host machine, you want to set up a ServerSocket object, and from the client machine you open a Socket. I don't have time to type up a whole example, but check this out for a simple way to set up a server-host connection over the Internet in Java.
http://zerioh.tripod.com/ressources/sockets.html
Once you get that set up, you want to input your shell command from the ServerSocket on the computer that should execute the command, and do something around the lines of
String command = "get this from the ObjectInputStream attached to your ServerSocket";
Runtime run = Runtime.getRuntime();
Process pr = run.exec(command) ;
pr.waitFor() ;
BufferedReader buffer = new BufferedReader( new InputStreamReader( pr.getInputStream() ) ) ;
String line;
while ( ( line = buffer.readLine() ) != null )
{
System.out.println(line);
}
The tricky part is setting up a realiable host-client connection with the Sockets, but if you're doing something simple you should be fine with the example from the link above.

Categories