I am looking for a solution to set of commands that need to be executed one after another in a sequential order. Again one command should execute only after the previous command is completed its execution.
String command="cd /home/; ls-ltr;"
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
System.out.println("DONE");
I tried executing command using ";" for each command but all the command are executed in a single attempt. So, its not working. What can be the possible approach to run each command in the same shell / exec.
I changed the implementation from "exec" to "shell" and update the command with "&&" between each command. Now the following command is executed only after the complete execution of the previous one. That is "&&" works in such a way that, based on the success status of the previous command i.e by checking the exit status which should be "0" else the following command wont be executed.
Updated code:
try{
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("Connected");
Channel channel=session.openChannel("shell");
OutputStream ops = channel.getOutputStream();
PrintStream ps = new PrintStream(ops, true);
channel.connect();
ps.println(command1 + "&&" + command2 + "&&" + command3 +"&&" +command4);
InputStream in=channel.getInputStream();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
channel.disconnect();
session.disconnect();
System.out.println("DONE");
}catch(Exception e){
e.printStackTrace();
}
You can use one command after another by appending them with &&. For example,
jschUtil.openChannel("exec");
jschUtil.getExecSshChannel().setCommand("cd /root/Test1/Test2 && mkdir Neel");
Here, Directory Neel will be created inside Test2. If you create 2 separate channel or use the commands one after the other, this will never be possible.
Related
I need run show interfaces status to Cisco/Alcatel switch via java (jsch if possible)
I use SSH to access this swith. after I try
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec) channel).setErrStream(System.err);
channel.setOutputStream(System.out);
InputStream in = channel.getInputStream();
channel.connect();
I try this (OK if I run manually command in console)
Channel channel = session.openChannel("shell");
channel.setInputStream(null);
channel.connect();
I need connect, send command and record the result of command. If I exec this manually the result is OK. I try my code in a virtual machine and the result is different to a physical switch.
You can try this :
Channel channel=null;
String result = null;
try
{
channel = session.openChannel("exec");
String Command = "show interfaces status"; // Command
//System.out.println("Command : "+Command);
((ChannelExec)channel).setCommand(Command);
InputStream in=channel.getInputStream();
byte[] tmp=new byte[1024];
channel.connect();
if(channel.isConnected())
{
//System.out.println("Channel connected");
}
while(true)
{ // geeting the result in this loop
while(in.available()>0)
{
int i=in.read(tmp, 0, 1024);
if(i<0)break;
result += new String(tmp, 0, i); // result
}
if(channel.isClosed())
{
break;
}
else
{
try{ Thread.sleep(1000); }catch(Exception ee){}
}
}
}
catch(JSchException e)
{
// your exception message
}
I have a requirement in automation where I need to stop the tomcat server located at Linux.. How can I do it?. I am trying multiple code-snippets using JSch but those are not working as expected. Can someone please help me here?
Here is my sample code -
java.util.Properties config = new java.util.Properties();
config.put("StrictHostKeyChecking", "no");
JSch jsch = new JSch();
session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig(config);
session.connect();
System.out.println("CONNECTED!");
String process = serverGetprocess();
LOG.info("ACTAUL SERVER PROCESS "+process);
commandStopServer = "kill -9" + process;
LOG.info(commandStopServer);
Channel channel = session.openChannel("exec");
((ChannelExec) channel).setCommand(commandStopServer);
channel.setInputStream(null);
channel.setOutputStream(System.out, true);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
Thread.sleep(1000);
byte[] tmp = new byte[1024];
while (true) {
while (in.available() > 0) {
int i = in.read(tmp, 0, 1024);
if (i < 0)
break;
System.out.print(new String(tmp, 0, i));
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
} catch (Exception ee) {
LOG.info("Inside catch of channel closing!");
}
}
channel.disconnect();
return true;
Here is the code to put within set command "pkill -9 -f tomcat" i.e;
((ChannelExec) channel).setCommand("pkill -9 -f tomcat");
I tried some commands such as
echo "Your text here" | ssh hostname 'cat >> output.txt'
but it didnt work.
How can I write in a file inside the server using this exec code or just the ssh command that I will put to String command.
public class TestWrite{
private static final String user = "username here";
private static final String host = "host here";
private static final String password = "pass here";
public static void main(String[] arg){
try{
JSch jsch=new JSch();
Session session=jsch.getSession(user, host, 22);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
String command = "Command here";
Channel channel=session.openChannel("exec");
((ChannelExec)channel).setCommand(command);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in=channel.getInputStream();
channel.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed()){
if(in.available()>0) continue;
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
channel.disconnect();
session.disconnect();
}
catch(Exception e){
System.out.println(e);
}
}
}
You can write to a file with
echo "your text here" > file
You don't need ssh because Jsch takes its place.
Try a command like:
ssh hostname 'echo "Your text here" >> output.txt'
I'm working on a project to restart something within a screen on a remote server using JSch... however I'm running into an issue. It will send the first 2 commands 100% of the time, but the 3rd command will only be sent some of the time. Any help would be appreciated.
public static void stopServer(String name, String ip, String passwd)
{
try {
Session session = Main.jsch.getSession("user",ip,22);
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(passwd);
session.connect();
Channel channel = session.openChannel("shell");
channel.connect();
ChannelShell cs = (ChannelShell) channel;
cs.setPty(true);
DataInputStream dataIn = new DataInputStream(channel.getInputStream());
PrintStream dataOut = new PrintStream(channel.getOutputStream());
dataOut.println("screen -x "+name);
dataOut.flush();
dataOut.println("stop");
dataOut.flush();
String line = dataIn.readLine();
System.out.println(line);
while(true) {
line = dataIn.readLine();
System.out.println(line);
if(line.contains("\"quit\""))
{
break;
}
}
TimeUnit.SECONDS.sleep(1);
dataOut.println("quit");
dataOut.flush();
System.out.println("Shutdown");
dataIn.close();
dataOut.close();
channel.disconnect();
session.disconnect();
}catch(Exception e)
{
e.printStackTrace();
}
}
This sends the screen -x 'name' and the stop 100% of the time from what I've seen, but the 'quit' command only actually gets sent/understood by the console a fraction of the time. Any help would be appreciated!!
I managed to fix this in a way that doesn't use the shell channel, but it is reliable enough that it works:
//Start EXEC
ChannelExec ce = (ChannelExec) session.openChannel("exec");
ce.setCommand("screen -S " + name + " -X stuff 'quit\n'");
ce.setInputStream(null);
ce.setErrStream(System.err);
InputStream in=ce.getInputStream();
ce.connect();
byte[] tmp=new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
//System.out.print(new String(tmp, 0, i));
}
if(ce.isClosed()){
if(in.available()>0) continue;
//System.out.println("exit-status: "+ce.getExitStatus());
break;
}
try{Thread.sleep(1000);}catch(Exception ee){}
}
ce.disconnect();
//STOP EXEC
As much as this doesn't work along the original vein of the problem, it fixed it for me.
If an exception gets thrown sometime before the "quit" command gets sent, then the quit command will never get sent.
If the while loop never breaks, then that will prevent the "quit"
command from being sent too.
My aim is to connect to my linux server using a java application and execute a linux command. I have already achieved this using the JSch API but I can't seem to figure out how to execute more than one command at a time.
It's a problem for me because I need to navigate to a certain directory, then execute another command FROM that directory. My application just exits before the second command can be executed in the correct directory.
Here is my method to execute one linux command as a string when it is passed as a parameter and print any output.
public void connect(String command1){
try {
JSch jsch = new JSch();
Session session = jsch.getSession(user, host, port);
session.setPassword(password);
session.setConfig("StrictHostKeyChecking", "no");
session.connect();
System.out.println("Connected");
Channel channel = session.openChannel("exec");
((ChannelExec)channel).setCommand(command1);
channel.setInputStream(null);
((ChannelExec)channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[1024];
while(true){
while(in.available()>0){
int i=in.read(tmp, 0, 1024);
if(i<0)break;
System.out.print(new String(tmp, 0, i));
}
if(channel.isClosed()){
System.out.println("exit-status: "+channel.getExitStatus());
break;
}
try {
Thread.sleep(1000);
}
catch(Exception ee){
ee.printStackTrace();
}
}
channel.disconnect();
session.disconnect();
System.out.println("DONE");
}
catch(Exception e){
e.printStackTrace();
}
}
Any ideas how to do 2 commands at once?
If a normal shell is started on the remote machine, use ; or && constructs to do more things.
As in
cd /home/foo/banana ; do_things
or
cd /home/foo/banan && do_things #do_things will only be run if the cd command is successfull