Ganymed_SSH2执行执行nohup命令失败

Ganymed_SSH2执行执行nohup命令失败

1 背景

   问题:“” 因为最近一个SQL同事离职,导致有一堆哔了狗的杂事儿全交接到我的手中。这些事儿比较简单却比较麻烦,比如每天都需要写几个shell命令去检查linux机上定时cron生成的数据是否:
假如当前Cron生成的文件有问题,就需要人工干预执行。如果人为不干预,会导致失败当天之后每天定时cron都会失败(理解成串行,一个失之后的数据生成都会失败)。

    当前遇到的问题便是该哥们已经块两个月没去监控数据,导致已经有两个月的数据生成失败。所以自己接过来的工作便是去每天哔了狗的去恢复这些数据,执行一批数据命令会花费大概4个小时,
从而导致自己每天都需要中断自己手上的事儿来处理这些杂事

   So,决定用Ganymed_SSH2包通过程序的方式来页面式的监控数据是否生成,然后提供页面方式来远程执行shell命令,从而避免来回切换工作环境。在使用这个包的项目过程中,
遇到了一个比较棘手的问题,相同问题的资料比较少,因此将该问题陈述如下比提供核心部分的代码,方便更多码蛆解决问题。

   问题:通过java代码无法创建nohup指定的进程

参考连接
http://northmelon.top/index.php/2019/10/09/error-running-shell-script-by-ganymed_ssh2/

2 代码

public  String execRemoteCommand(String command, long timeout)
            throws Exception {
        Connection conn = getConnection();
        StringBuilder sb = new StringBuilder();
        Session session = null;
        try {
            session = conn.openSession();
            session.requestPTY("vt100", 80, 24, 640, 480, null);
            session.execCommand(command);
            InputStream stdout = new StreamGobbler(session.getStdout());
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            long start = System.currentTimeMillis();
            char[] arr = new char[512];
            int read;
            int i = 0;
            while (true) {
                read = br.read(arr, 0, arr.length);
                if (read < 0 || (System.currentTimeMillis() - start) > timeout * 1000) {
                    break;
                }
                sb.append(new String(arr, 0, read));
                i++;
            }
        } finally {
            if (session != null) {
                session.close();
            }
            if (conn != null) {
                conn.close();
            }
        }
        return sb.toString();
    }

   代码参考链接

https://blog.csdn.net/pengchang_1981/article/details/8095683

3 问题定位

3.1 测试其它和当前需要执行nohup命令

   其它测试命令没问题,如ls、mkdir、cp、mv,这些命令的结果能顺利的返回到java端

   将需要运行的nohup命令直接在linux机上运行没问题

3.2 SSH链接超时问题

   由于nohup创建的后台进程执行时间可能长达几个小时,而代码一直在循环等待输出,所以怀疑是否是长时间导致ssh断开。

   由于代码只需要启动后台进程,无需关心返回值,所以直接在代码中省去了获取返回值。之后测试,发现还是不生效。

3.3 环境变量

   在无意中发现另外的帖子提供了解决思路。通过方法execCommand执行Shell命令的时候,会遇到获取不全环境变量的问题

https://my.oschina.net/tacg/blog/423982

https://www.cnblogs.com/-wangjiannan/p/3751330.html

4 更改后代码

public void execEmoteCommand(String command, long timeout)
            throws Exception {
        Connection conn = getConnection();
        Session session = null;
        try {
            session = conn.openSession();
            session.requestPTY("bash");
            session.startShell();
            PrintWriter out = new PrintWriter(session.getStdin());
            out.println(command);
            out.println("exit");
            out.close();
            session.waitForCondition(ChannelCondition.CLOSED | ChannelCondition.EOF | ChannelCondition.EXIT_STATUS, timeout*1000);
        } finally {
            if (session != null) {
                session.close();
            }
            if (conn != null) {
                conn.close();
            }
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值