baipeifa 2013-08-28 16:16 采纳率: 0%
浏览 2193

java实现ssh登录远程Linux服务器并在该服务器上执行命令的问题

请教高手:
现在要使用java实现ssh登录远程Linux服务器并在该服务器上执行命令,获得执行命令的结果!由于采用的ssh登录方式是使用公钥密钥对的形式,不需要输入密码。所以如果正常的话可以直接执行,能很快得到结果。
但要是不小心出现问题,比如公钥密钥丢失等情况,就会需要输入密码,这时候程序就会一直停留在等待输入密码的那一步,无法继续执行下去。
现在假设发生了后面那种事情(需要输入密码,程序一直停留在等待密码),我需要的是程序能直接返回来,并告诉我说需要密码无法登陆。这个该怎么实现??

  • 写回答

1条回答 默认 最新

  • ChatGPTᴼᴾᴱᴺᴬᴵ 2023-01-13 19:37
    关注

    你可以使用 JSch 库来实现这个功能。 JSch 是一个 Java 实现的 SSH 库,支持公钥密钥对登录方式。你可以使用 JSch 的 setUserInfo 方法来设置一个 UserInfo 实例,该实例可以在需要密码时返回一个特定的值,从而使程序知道需要密码却无法登录。

    import com.jcraft.jsch.*;
    
    public class SSHExample {
    
        public static void main(String[] args) {
    
            JSch jsch = new JSch();
    
            try {
                Session session = jsch.getSession("username", "hostname", 22);
                session.setUserInfo(new MyUserInfo());
                session.connect();
                Channel channel = session.openChannel("exec");
                ((ChannelExec)channel).setCommand("ls -l");
                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){}
                }
                channel.disconnect();
                session.disconnect();
            } catch (JSchException e) {
                System.out.println("Error: " + e.getMessage());
            } catch (IOException e) {
                System.out.println("Error: " + e.getMessage());
            }
        }
    
        private static class MyUserInfo implements UserInfo {
            @Override
            public String getPassphrase() {
                return null;
            }
            @Override
            public String getPassword() {
                return null;
            }
            @Override
            public boolean promptPassword(String message) {
                return false;
            }
            @Override
            public boolean promptPassphrase(String message) {
                return false;
            }
            @Override
            public boolean promptYesNo(String message) {
                return false;
            }
            @Override
            public void showMessage(String message) {
                System.out.println("Error: " + message);
            }
        }
    }
    

    在上面的代码中,MyUserInfo类实现了UserInfo的接口,并重写了promptPassword方法,在这个方法中,你可以返回false值来告诉程序无法登录需要密码。


    在main方法中,你可以使用JSch的getSession方法来连接远程服务器,并使用setUserInfo方法来设置你的MyUserInfo实例。在连接建立后,你可以使用Session的openChannel方法来打开一个Channel实例并执行你需要的命令。


    这个示例代码仅仅是一个示例,你可能需要根据你的实际需求来进行更改和完善。

    评论

报告相同问题?

悬赏问题

  • ¥15 Stata 面板数据模型选择
  • ¥20 idea运行测试代码报错问题
  • ¥15 网络监控:网络故障告警通知
  • ¥15 django项目运行报编码错误
  • ¥15 请问这个是什么意思?
  • ¥15 STM32驱动继电器
  • ¥15 Windows server update services
  • ¥15 关于#c语言#的问题:我现在在做一个墨水屏设计,2.9英寸的小屏怎么换4.2英寸大屏
  • ¥15 模糊pid与pid仿真结果几乎一样
  • ¥15 java的GUI的运用