【问题标题】:Remove special characters while using "more" command from Java using JSCH?使用 JSCH 从 Java 中使用“更多”命令时删除特殊字符?
【发布时间】:2014-09-15 21:08:18
【问题描述】:

我在 UNIX 服务器上有一个动态变化的日志文件。

我想构建一个应用程序,以使用 SSH 在多个页面中使用 Swings 在 Java GUI 上查看该文件。

我正在使用 JSCH 库为该日志文件执行“更多”命令。但在输出中,会打印一些特殊字符,例如 '[24;1H[K[7m' ]。如何删除这些特殊字符。

我正在使用以下代码

session.setConfig("StrictHostKeyChecking", "no");   
session.connect(30000);
Channel channel=session.openChannel("shell");
channel.setInputStream(System.in);
channel.setOutputStream(System.out);            
channel.connect();           
Thread.sleep(3000);  
PrintStream ps = new PrintStream(channel.getOutputStream(), true);
ps.println("more " + fileName);

输出是:

[?7h[?1l(B=[24;1H[K************ Start Display Current Environment ************
[24;1H[K[7mSystemOut.log (0%)[m[24;1H[24;1H[KID: soacore.FP6123  BuildVrsn: null  Desc: WebSphere Process Server 6.1.2.3
[24;1H[K[7mSystemOut.log (0%)[m

如您所见,打印了一些特殊字符。如何去除那些特殊字符?

【问题讨论】:

  • “无法分页查看日志文件”是什么意思?
  • 我的意思是我想查看日志文件,就像使用 UNIX 分页实用程序(更多命令,更少命令)显示的一样。由于文件不断变化,我无法将文件 ftp 到本地系统。
  • 运行more程序会发生什么?
  • 我已经更新了问题。我已经包含了代码 sn-p 和输出。现在问题会更清楚。请帮忙。
  • 当您可以使用 Sftp 获取文件时,为什么还要使用“更多”命令运行交互式 shell?

标签: java unix ssh jsch


【解决方案1】:

如果您正在开发终端模拟器,您可以考虑使用第三方库来帮助您管理输入数据流,特别是处理您遇到的the ANSI terminal control characters。像Expect 这样的工具传统上用于自动化程序和基于文本的终端系统之间的交互。

您可以使用几个现有的Expect for Java 实现。在这里,我想推广我自己的开源工具ExpectIt。它支持过滤输入数据以删除不需要的字符,例如您可能会发现对您的用例非常有用的终端控制。它具有项目页面上所述的其他优点。

这里是一个使用 ExpectIt 遍历more 命令结果的示例。请注意注册removeColors 过滤器,其中filters 输出终端字符。

    session.setConfig(config);
    session.connect();
    Channel channel = session.openChannel("shell");

    Expect expect = new ExpectBuilder()
            .withOutput(channel.getOutputStream())
            .withInputs(channel.getInputStream(), channel.getExtInputStream())
            // register filters to remove ANSI color characters
            .withInputFilters(removeColors())
            .build();
    try {
        channel.connect();
        // define the command line prompt
        final String PROMPT = "...";
        expect.expect(contains(PROMPT));
        expect.sendLine("more <file>");

        while (true) {
            // expect either the end of the page or the end of the command
            MultiResult result = expect.expect(anyOf(contains("--More--"), contains(PROMPT)));
            // print the result
            System.out.println(result.getBefore());
            // exit if reach the end
            if (result.getResults().get(1).isSuccessful()) {
                break;
            }
            // scroll to the next page
            expect.send(" ");
        }

下面的代码假设相应的方法是静态导入的。

【讨论】:

  • 我之前从未使用过Expect API。所以,我对 Expect 库很天真。你能告诉如何将它用于“更多”命令吗?在此先感谢:)
  • @Jhamb 我已经用“更多”命令的示例更新了我的答案。
  • 非常感谢! :) 但是仍然会打印一些不需要的字符,例如 [?7h[?1l(B=ent (0%)[24;1 有没有办法删除这些字符。提前致谢!
  • @Jhamb 您可以尝试使用“removeNonPrintable”过滤器。如果它没有帮助,那么您可以根据正则表达式编写自己的。参考这个页面:github.com/Alexey1Gavrilov/ExpectIt#filtering-the-input
  • ExpectIt 中的 replaceInBuffer 和 replaceInString 过滤器有什么区别?
【解决方案2】:

我找到了答案。只需一行代码即可。

((ChannelShell) channel).setPtyType("dumb");

在 connect() 之前添加上述行会删除所有不可打印的字符。

【讨论】:

    猜你喜欢
    • 2018-06-13
    • 1970-01-01
    • 2021-07-01
    • 2016-03-10
    • 2019-08-27
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多