JSch executing multiple linux commands in one session - java

I'm working on a project in which I intend to make a Java GUI application that connects to a ssh server and executes remote commands on the server. I'm willing to use JSch Library. My aim is to make buttons and textfields those will provide the user the ability of sending commands and getting replies easily. I mean, instead of opening xShell and prompting "grep "hi" /usr/file.txt", the user will choose the path from the list and will enter "hi" into the textfield and will press the button for grep.
Problem is, I couldn't find a solution to execute multiple linux commands in one session (I don't want shell if i cannot redirect its input and output streams) (also I don't want the solution "cd.. \n dir \n ls -l" which works fine but not solving my problem) send the arguments those shall be taken from related GUI components.
Since I have not made so much modifications on the JSch's example code, yet, you can see the code here: http://www.jcraft.com/jsch/examples/Exec.java.html
Thanks from now on.

If using exec type of channel you can combine commands with && :
channel.setCommand(". ./.profile && env");

Related

"Smart" scripting via SSH using Java

I want to write a program which controls a tool on a remote server. For that I want to create a SSH-Method to connect to the remote server and execute some commands to get some data. Sadly I don’t find a way to handle the SSH part properly.
Here is a flowchart showing what the method should be able to do:
First I want to connect via SSH to the remote server. I successfully tried that with “JSch”.
After that, the method should enter the command ls -l into the shell and wait for the response. Now it should parse the output, and act differently depending on the output.
If there is a folder with the name “folder123”, the next commands should be to change into this folder (cd folder123) and enter ls -l there again. This list of content then should be returned and the ssh connection can be closed.
If the folder doesn’t exist, the program should create one (mkdir folder123) and then return a code (-1).
In my main program I will use the new data to make some decisions and then going on.
I found ways with JSch to execute one command, like ls -l and even multiple commands and get the response back as a string. Sadly, I have to pass all commands in one block for that, so I have no way to make the decision in the middle of it. When I want to implement decision making, I have to close the connection first. That would lead to a lot of connection building overhead, especially when there will be more than one decision to make and I have multiple navigating steps between them.
So is there a way to make this decision while the connections stays establish, so I can directly enter the next command after it?
Edit:
I am just playing around by now. So my solution with the multiple commands is basically the answer from Mihail in this post
For this part of the task it would be more simple to use the ways DaveyDaveDave and Aaron proposed. But i have to do some more specific tasks.I thought it is the best to provide a simple example first, but here is another one which needs to use a program on the remote server:
Another Example
After the ssh connection is established (the only non-graphical way to access this server), I have to login in the tool (that is a one-liner the command line).
In the cmd, and through this in my ssh connection, i get an output after that. It shows some information about the user and ends with the word "END" and above that i have a return code. The function has to wait for the "END" and then parse the return code. Depending on it, the function should try again or enter the next command.
After the next command it has to do the same validation and when everything worked until now, the last output should be returned to the main program (in this it contains network elements and information about them).
Found an fitting answer for my problem in another Thread where I asked a more specific question.
Look here if you have similar problems:
Change System.in and read System.out programmly on the fly (Jsch)

Using 'become' command in Java JSch program to access a restricted directory

Working with Unix server... My requirement is to read the name of the file that is there at /a/b/c/node01/d.ear location on a Unix server and I have do the same through a java program. The problem is that the directory a is a restricted directory and is accessible only to certain users. On the Unix side, I first issue a become command like become a, then supply the password and then using cd command, I reach the d.ear directory and then get to see the name of the file.
How do I do all of this via a Java program?
I don't mind if my Java program calls a shell script that accesses the restricted directory and then reach d.ear and fetch the name of the file and returns the same to the java program. Do we have a way of doing this? Maybe issuing the become command inside the script which is called from the Java program and the password which is asked after become command is supplied as a parameter while calling the script???
Is this approach doable? I am very new to Unix commands and JSch library. Kindly provide the code or any other alternate solutions...
Thanks!!!
As I have suggested you already, your become command seems to behave the same way (from an interface/API point of view) as common *nix su or sudo.
So, use the same solution as for those. There are many questions on Stack Overflow covering use of su/sudo with JSch.
There's even an official JSch example Sudo.java:
http://www.jcraft.com/jsch/examples/Sudo.java.html
In short:
Execute become command
Feed a password to its input
Assuming the become starts a new shell (as su or sudo do), you feed the commands to be executed in the elevated environment to become input (the same was as the password).

How to type in commands automatically in cmd window at a high speed in order to test program reliability?

I made a simple chat room application consists of a client.jar and server.jar. After running the .jar file in cmd window, I need to type in some specified command in client part and carriage return to run the application, such as "#connect": connect to the server, "#send XXX": send XXX message to server and broadcast to other connected clients...
Here comes the problems. Actually I want to test how the application works well when there exist concurrency. So I think I need try to let two or more client parts send the command repeatedly and fast. But obviously i cannot achieve manually.
Is there any ways can let the system get the command and send it automatically at high speed? I guess using batch file is suitable for this issue, but I am not sure or how to implement it...

Embedding a terminal Window inside of a simple scala application

I'm trying to build a simple text editor using Scala's swing library and I have to support two side by side windows. I was wondering if it was possible to have the second window be the terminal (bash, Unix). I haven't been able to find any information on the subject. Thank you for any information.
The question is: What is "the terminal"? bash is a shell but you need an implementation of a terminal which runs a certain shell. In general, I would say there are two possibilities:
Find a terminal implementation, which can be used directly in Swing. Maybe you this or that may help.
Implement your own terminal. You may want to start to wrap the shell with a ProcessBuilder. Now you can redirect standard input and output of this process so that you can control it programmatically (more information: here and there). Then you have to create the UI part which (1) reads input from the user and (2) displays the shell output in your window.

Running commands over ssh with Java

Scenerio: I'd like to run commands on remote machines from a Java program over ssh (I am using OpenSSH on my development machine). I'd also like to make the ssh connection by passing the password rather than setting up keys as I would with 'expect'.
Problem: When trying to do the 'expect' like password login the Process that is created with ProcessBuilder cannot seem to see the password prompt. When running regular non-ssh commands (e.g 'ls') I can get the streams and interact with them just fine. I am combining standard error and standard out into one stream with redirectErrorStream(true); so I am not missing it in standard error...When I run ssh with the '-v' option, I see all of the logging in the stream but I do not see the prompt. This is my first time trying to use ProcessBuilder for something like this. I know it would be easier to use Python, Perl or good ol' expect but my boss wants to utilize what we are trying to get back (remote log files and running scripts) within an existing Java program so I am kind of stuck.
Thanks in advance for the help!
The prompt might only be shown when ssh is connected to a TTY, which it isn't in the case of Java.
There's probably a way to supply the password on the command-line in your ssh application. That will be the way to get past the prompt.
Alternately, consider connecting directly to the host server from native Java code rather than running an external application. There's a million libraries that will do this.
Rather than using an external ssh program, why not use a Java ssh library:
Trilead
JTA
Are two I found with google - that'll avoid the problem that openssh will be working very hard to prevent entering the password on stdin - it'll be opening the terminal directly. expect has to work very hard to simulate a tty in order to work.
Why not use a Java ssh client? This one is BSD-licensed, and there are more clients listed here.
Most security minded programs don't use stdin/stdout for capturing passwords, they capture the TTY or some equivalent method.
Echoing others' suggestion to use a Java SSH library. But wanted to comment on Cohen's response. Sending your password over the command line when establishing the connection is insecure and also not permitted by many sshd servers (based on configuration).
You might want to look into setting up keys for this, so you can perform ssh commands between the machines without a password.
Basic steps
- use openssh to create a keypair (I've done RSA but I know there's a better method now)
- create a .ssh directory in your home folder on the SOURCE machine
- create a .ssh directory in your home folder on the TARGET machine
- keep your private key in your source machine's .ssh folder
- copy your public key into a file called authorized_keys in the target's .ssh folder
Some instructions can be found here
You can run commands using edtFTPj/PRO, as well as performing file transfers via SFTP. It's Java.

Categories

Resources