java连接linux交互式

原文参考:

http://www.codeproject.com/Articles/46891/Remote-interactive-SSH-command-in-Java

 

Remote interactive SSH command in Java

 

Introduction

This article presents a way to implement a remote connection to a server via SSH (secure shell) and to execute an interactive command through a pseudo terminal in Java.

Background

Programs which implement a remote connection to a server to execute a command via SSH (secure shell) in Java are very common, but most of them can only execute the "exec" command (non interactive cmd, in other words, execute command and hand over the control as soon as the cmd is finished, such as "date" to display the current time, and can not execute "ls' to display the file list under a designated directory (opt/3com/VCX/vcxdata/). This article will show a way to execute those commands, and further, interactive commands (such as "su root", which will claim the password, and we will input the password according to the output we get in real time).

Using the Code

First, import an external jar package sshtools. Then, declare an instance of SshClient and SessionChannelClient. You may have noticed that the way to get session output is a little different. We do not declare an object of ChannelOutputStream; instead, an object of SessionOutputReader, a point to which I will return.

 

import com.sshtools.j2ssh.SshClient;
import com.sshtools.j2ssh.authentication.PasswordAuthenticationClient;
import com.sshtools.j2ssh.session.SessionChannelClient;
import com.sshtools.j2ssh.session.SessionOutputReader;
import com.sshtools.j2ssh.transport.IgnoreHostKeyVerification;

 

As we are going to login to the 3com VCX server through SSH, the server IP, user name, and password are required, and set as shown below:

final private String username = "root";
final private String password = "pvadmin";
final private String hostname = "172.31.50.102";
private int outputPos = 0 ;

 

After executing the command, we get the output as a string. The previous output will be included in the current string to avoid the output being displayed over and over. We set outputPos as the offset from where the output will be displayed.

ssh = new SshClient();
try{
    ssh.connect(hostname, new IgnoreHostKeyVerification());

 

Create an SSH client to connect to server via SSH, and ignore the host key verification.

 

PasswordAuthenticationClient pwd = new PasswordAuthenticationClient();
pwd.setUsername(username);
pwd.setPassword(password);
int result = ssh.authenticate(pwd);
 

 

The result must be 4; otherwise, it means the SSH connection is not set up properly.

 

if (result == 4)
{
   logCat.info("Connected to host");
   session = ssh.openSessionChannel();
   sor = new SessionOutputReader(session);
 Open a session channel after connecting to the server successfully, and create an instance of the session output reader of the session.

 

 

if (session.requestPseudoTerminal("gogrid",80,24, 0 , 0, ""))
 

 

Create a pseudo terminal to connect to the server. The terminal type could be dumb, xterm, gogrid, vt100, vt220, vt320 etc., but I strongly recommend to choose "gogrid", for the others will result in confusing characters.

Here is the the prototype of the requested pseudo terminal:

 

boolean requestPseudoTerminal(String term, int cols, 
          int rows, int width, int height, String modes)

if (session.startShell())
{
    in = (session.getInputStream());
    logCat.info(in);
    out = session.getOutputStream();
    out.write("cd opt/3com/vcx/vcxdata/\n".getBytes());
    out.write("ls\n".getBytes());

 

If it succeeds in starting the shell, execute the following command: "cd /opt/3com/vcx/vcxdata/". Then, "ls" to display the file list under that directory.

 

Thread.currentThread().sleep(1000*2);
String answer = null;
String aux = null;
aux = sor.getOutput();   
answer = aux.substring(outputPos);
outputPos = aux.length();
logCat.info(answer);

 

After executing the command, check the output.

Similarly, we can execute interactive commands according to the last output prompt of the server in real time. For example, we get the cworks privilege, then we want to get back to the root privilege using the "su root" command, and the password prompt will be claimed. We check the output, and when we get the password prompt, we input the password.

out.write("su cworks\n".getBytes()); // input command su cworks 
out.write("su root\n".getBytes());
//  then input command su root which will claim password

Thread.currentThread().sleep(1000*2);
//verify what we have got  
String answer = null;
String aux = null;
aux = sor.getOutput(); // get the output in real time 
answer = aux.substring(outputPos);
outputPos = aux.length();
logCat.info(answer);
String str[] = answer.split("\n");
String prompt = str[str.length-1];   // get the last prompt
prompt = prompt.trim();
if (prompt.contains("Password:"))
// if the last prompt is "password 
{
   // then we input password.
   out.write("pvadmin\n".getBytes());
}

 

And again, check what we have got this time:

Thread.currentThread().sleep(1000*2);
aux = sor.getOutput();        
answer = aux.substring(outputPos);
logCat.info(answer);

 

Thanks to SessionOutputReader, we can read the output stream of the session in real time. So, we can decide what command we should input according to the output prompt of the server, which is the very essence of being interactive.

Points of Interest

I will be glad if this is helpful to you. And thank you for your advice, which helped me make this article better.

Reference: http://upcommons.upc.edu/pfc/bitstream/2099.1/3790/1/53848-1.pdf.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值