当前位置: 首页 > 面试题库 >

从ssh命令以创建命令的相同顺序记录stdout和stderr

袁泰
2023-03-14
问题内容

简短版本: 是否可以将sdout和stderr记录在通过ssh远程执行的命令的本地端上,其顺序与在远程主机上输出的顺序相同?如果是这样,怎么办?

长版:

我试图记录远程执行的SSH命令(使用Jsch)的标准和错误输出,其顺序与远程命令的输出顺序相同。换句话说,如果远程命令将“ a”写入stdout,然后将“
b”写入stderr,然后将“ c”写入stdout,则我希望客户端(本地)端的日志读取为:

a
b
c

以下是我到目前为止的内容。它相对接近我想要的,但是我认为很明显,它不能保证客户端的正确输出顺序。

public int exec(String strCommand) throws ExceptionUnableToExecCommand {
    JSch jsch = new JSch();
    Session session = null;
    ChannelExec channel = null;
    try {
          session = jsch.getSession(user, host, 22);
          UserInfo ui = new cyclOps.jsch.UserInfo(password);
          session.setUserInfo(ui);
          session.connect();
          channel = (ChannelExec) session.openChannel("exec");
          channel.setCommand(strCommand);
          channel.setInputStream(null);
          InputStream in = channel.getInputStream();
          InputStream err = channel.getErrStream();
          channel.connect();
          /* getOutput() defined below. */
          return this.getOutput(channel, in, err);
    } catch (JSchException | IOException e) {
        throw new ExceptionUnableToExecCommand("Unable to execute " + strCommand + " " + this.toString(), e);
    } finally {
        if (channel != null) channel.disconnect();
        if (session != null) session.disconnect();
    }
}

private int getOutput(ChannelExec channel, InputStream in, InputStream err) throws IOException { 
    byte[] tmp = new byte[1024];
    while(true){
        while(in.available() > 0){
            int i=in.read(tmp, 0, 1024);
            if(i<0)break;
            this.sshLogger.logOutputFromSSH(new String(tmp, 0, i));
        }
        while(err.available() > 0){
            int i=err.read(tmp, 0, 1024);
            if(i<0)break;
            this.sshLogger.logOutputFromSSH(new String(tmp, 0, i));
        }
        if(channel.isClosed()){
            return channel.getExitStatus();
        }
        try{Thread.sleep(1000);}catch(Exception ee){}
    }
}

我想我应该指出,这是Jsch网站示例中Exec.java的修改版本。


问题答案:

下面的代码块怎么样?

channel.setCommand(command);

PipedOutputStream pos=new PipedOutputStream();
PipedInputStream pis=new PipedInputStream(pos);
channel.setOutputStream(pos);
channel.setExtOutputStream(pos);
InputStream in=pis;

channel.connect();


 类似资料:
  • 通过@HystrixCommand注释,可以配置一个回退方法,在方法失败的情况下运行该方法。

  • mkdir 命令,是 make directories 的缩写,用于创建新目录,此命令所有用户都可以使用。 mkdir 命令的基本格式为: [root@localhost ~]# mkdir [-mp] 目录名 -m 选项用于手动配置所创建目录的权限,而不再使用默认权限。 -p 选项递归创建所有目录,以创建 /home/test/demo 为例,在默认情况下,你需要一层一层的创建各个目录,而使用

  • 问题内容: 假设我的当前目录是 一个 。我想创建一个目录 乙 和文件“myfile.txt的”内部 乙 。 如何在终端的一个命令中做到这一点? 编辑: 目录可以嵌套多次。就像我可能要创建 B / C / D ,然后在其中创建“ myfile.txt”。我也不想重复目录部分。 以下命令将在任何级别创建目录。 和 将创建目录和文件。但是我不想在命令后重复目录部分。那可能吗? 问题答案: 或者,创建一个

  • 我们试图从Java程序调用Linux命令。我们能够从Java调用相当多的命令,包括和而没有任何问题。但是,失败。示例源代码如下: 引发的异常

  • 本文向大家介绍laravel 创建命令行命令的图文教程,包括了laravel 创建命令行命令的图文教程的使用技巧和注意事项,需要的朋友参考一下 1. 在命令行输入 php artisan make:command NiceWork(此处根据自己想要创建的命名) 2. 命令完成后,会在 目录中看到这个文件 3. 进入Console/Kernel.php , 注册该命令 4. 然后进入 NiceWor

  • # 查看已下载的Docker镜像latest具体版本 # docker image inspect redis:latest|grep -i version docker image inspect 镜像名:latest|grep -i version # 容器日志过大处理 # Docker 的日志文件存在 /var/lib/docker/containers 目录中,通过下面的命令可以将日志文