I have a program that implements the Eclipse Console as follows:
FAQ How do I write to the console from a plug-in?
Then i use the (MessageConsole) mainConsole).newMessageStream() to redirect the OutputStream of a Jsch Channel to my new console.
PrintStream printStream = new PrintStream(((MessageConsole) mainConsole.newMessageStream());
JSch jsch = new JSch();
Session session = jsch.getSession(username, host, port);
Channel channel = session.openChannel("shell");
channel.setOutputStream(printStream);
Now i want redirect the same OutputStream of the Jsch Channel to a file, the problem is that is already redirect to my console.
How i can do it at the same time.
Thanks.
If you're simply outputting text, you can try :
PrintWriter out = new PrintWriter("filename.txt");
Then, write your String to it, just like you would to any output stream:
out.println(text);
You'll need exception handling, as ever. Be sure to call out.close() when you've finished writing.
If you are using Java 7 or later, you can use the "try-with-resources statement" which will automatically close your PrintStream when you are done with it (ie exit the block) like so:
try (PrintWriter out = new PrintWriter("filename.txt")) {
out.println(text);
}
You will still need to explicitly throw the java.io.FileNotFoundException as before.
Related
I want to:
Log in to putty using Hostname, username, password and port number.
This I have achieved.
Once I logged in, I want to connect to server1. Usually in putty we
connect using ssh command (ssh user#server1).
Once I connected to that server.I need to run multiple commands like:
df -kh ps -ef|grep www
And after executing above commands, I need to log out from
server1 and need to log in to server2.
How can I do it in JSCH?
JSch jsch=new JSch();
Session session=jsch.getSession(remoteHostUserName, RemoteHostName, remoteHostPortNo);
session.setPassword(remoteHostpassword);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
System.out.println("Please wait...");
session.connect();
System.out.println("Connected "+remoteHostUserName+"#"+RemoteHostName);
ChannelExec channel=(ChannelExec) session.openChannel("shell");
BufferedReader in=new BufferedReader(new InputStreamReader(channel.getInputStream()));
channel.setCommand("df -kh");
channel.setCommand("pwd");
channel.connect();
Try ChannelShell channel = (ChannelShell) session.openChannel("shell"); setup inputStream and outputStream and subsequently perform the following loop:
write into the connected inputStream and flush it
read from the connected outputStream
This way you can even construct your second commands based on the outcome of the first one.
In order to create an interactive session, you can refer the Example class provided jsch developers.
http://www.jcraft.com/jsch/examples/UserAuthKI.java
Create the Channel object as an instance of Shell
ie
Channel channel=session.openChannel("shell");
And then set the Input and Output Streams for that Channel object.
channel.setInputStream(System.in);
channel.setOutputStream(System.out);
And then connect the channel.
This way, after each comand execution, the channel won't be closed and the state of the previous command can be persisted.
Using the above code, you can create an interactive session in your console
You can run multiple commands by using below approach
put all the commands in a string separated by ;
"command1;command2...."
I am trying to run the "net use" command by invoking it using process builder. As I pass the password to the OutputStream using PrintWriter it fails with the following error :
System error 1219 has occurred.
Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.
I have checked the username, password and the command, by running it manually. Its working fine
The code snippet :
ProcessBuilder pb = new ProcessBuilder("net","use","\\\\<SERVERNAME>\\<SharedLocation>","/USER:<username>","*");
Process p = pb.start();
OutputStream out = p.getOutputStream();
PrintWriter writer = new PrintWriter(out);
writer.println("<pwd>".toCharArray());
int exitCode = p.waitFor();
System.out.println("Exit Code :"+ exitCode);
A couple of suggestions:
Run net use * /delete /y as your first step to remove all connections before you start. You can also try removing specific connections.
Use a pure Java solution instead of net use -- see https://stackoverflow.com/a/208896/4803
Hi i want to write a java program in Linux machine which should read a file in another remote Linux machine and copy its contents to the source machine. I am using the following code for it
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
System.out.println("Establishing Connection...");
session.connect();
System.out.println("Connection established.");
System.out.println("Crating SFTP Channel.");
ChannelSftp sftpChannel = (ChannelSftp) session.openChannel("sftp");
sftpChannel.connect();
System.out.println("SFTP Channel created.");
InputStream out = null; //.get(remoteFile);
out = sftpChannel.get(pub);
System.out.println("Read Successful");
System.out.println(pub);
StartString = pub.split("/");
i=StartString.length;
fileName =LocalWrite+StartString[i-1];
System.out.println(fileName);
OutputStream fileOut = new FileOutputStream(new File(fileName));
byte[] buf = new byte[1024];
int len;
while ((len = out.read(buf)) > 0) {
fileOut.write(buf, 0, len);
}
System.out.println("Wrote Successfull");
out.close();
fileOut.close();
sftpChannel.disconnect();
session.disconnect();`
When i try this i am getting a fileNotFound Exception but when i try the same code in Windows Machine i am able to read the file and copy its contents to my local machine. Could you tell me where i am doing the mistake.
Hard to tell without more information. A wild guess (suggested in the comments): Did you use the correct pathname for the Linux system (which will be different to the name on Windows)? Did you pay attention to upper/lower case?
To debug this further, you could run sshd (the SSD daemon) in debug mode on the target Linux system. Then try to connect, and see what file name arrives on the target system, and why it does not find it.
Hi the problem has been solved. The two machines are in Different Networks hence the above code was not working.
InetAddress host = InetAddress.getLocalHost();
Socket link = new Socket(host, Integer.parseInt(args[0]));
System.out.println("before input stream");
ObjectInputStream in = new ObjectInputStream(link.getInputStream());
System.out.println("before output stream");
ObjectInputStream out = new ObjectOutputStream(link.getOutputStream());
"before input stream" is the last lifesign on cmd-line. There is no Exception thrown. Why is this happening? I don't understand...
args[0] is 5000.
//edit: flush doesn't help.
This is because the ObjectInputStream(InputStream in)-constructor is a blocking-call if the inputStream is empty.
Quote:
Creates an ObjectInputStream that reads from the specified InputStream. A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
Possibly,
link.getInputStream();
could be returning null, though that should return an error by looking at the class files.
Another thing I noticed was, you declare:
ObjectInputStream out = new ObjectOutputStream(link.getOutputStream());
From this, you are stating a ObjectInputStream as a ObjectOutputStream without a cast (Would not be appropriate here anyways)
you should try:
ObjectOutputStream out = new ObjectOutputStream(link.getOutputStream());
This should work, as the script may queue the System.out, but notice the error before it can be initialized.
Tell me if this works :D
I am new to SSH and JSch. When I connect from my client to the server I want to do two tasks:
Upload a file (using ChannelSFTP)
Perform commands, like creating a directory, and searching through a MySQL database
At the moment I am using two separate shell logins to perform each task (actually I haven't started programming the MySQL queries yet).
For the upload the relevant code is
session.connect();
Channel channel=session.openChannel("sftp");
channel.connect();
ChannelSftp c=(ChannelSftp)channel;
c.put(source, destination);
And for the command I have
String command = "ls -l";//just an example
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
Should I disconnect the session after the first channel and then open the second channel? Or close the session entirely and open a new session? As I said, I'm new to this.
One SSH session can support any number of channels - both in parallel and sequentially. (There is some theoretical limit in the channel identifier size, but you won't hit it in practice.) This is also valid for JSch. This saves redoing the costly key exchange operations.
So, there is normally no need to close the session and reconnect before opening a new channel. The only reason I can think about would be when you need to login with different credentials for both actions.
To safe some memory, you might want to close the SFTP channel before opening the exec channel, though.
To give multiple commands through Jsch
use shell instead of exec.
Shell only support native commands of the connecting system.
For example, when you are connecting windows system you can't give commands like dir using the exec channel.
So it is better to use shell.
The following code can be used to send multiple commands through Jsch
Channel channel = session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
ps.println("mkdir folder");
ps.println("dir");
//give commands to be executed inside println.and can have any no of commands sent.
ps.close();
InputStream in = channel.getInputStream();
byte[] bt = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(bt, 0, 1024);
if (i < 0) {
break;
}
String str = new String(bt, 0, i);
//displays the output of the command executed.
System.out.print(str);
}
if (channel.isClosed()) {
break;
}
Thread.sleep(1000);
channel.disconnect();
session.disconnect();
}