0

I have a log file on a UNIX server which is dynamically changing.

I want to build an application to view that file on a Java GUI using Swings in multiple pages using SSH.

I am using JSCH Library to execute the "more" command for that log file. But in the output, some special characters like '[24;1H[K[7m' are printed. How to remove these special characters.

I am using the following code

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);

The output is :

[?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

As you can see, some special characters are printed. How to remove those special characters?

Jhamb
  • 31
  • 4
  • 1
    What do you mean by "it is unable to view the log file in multiple pages"? – Kenster Jul 24 '14 at 12:51
  • I mean that i want to view the log file like it is displayed using UNIX Paging utilities (more command, less command). As the file is continuously changing, I cannot ftp the file to local system. – Jhamb Jul 25 '14 at 07:12
  • What happens when you run the more program? – Kenster Jul 25 '14 at 12:44
  • I've updated the question. I have included code snippet and output. Now the question will be more clear. Please help. – Jhamb Jul 26 '14 at 10:29
  • Why would you want to run an interactive shell with the "more" command when you can just use Sftp to get the file across? – Erwin Bolwidt Jul 29 '14 at 13:44
  • Actually the file is continuously changing. So using Sftp to get the file is not the solution. Because everytime the file changes, i have to load the file again. – Jhamb Jul 30 '14 at 05:50
  • Those characters are terminal escape sequences. `more` is trying to control the terminal that the text is displaying in. What kind of interface (terminal or otherwise) are you actually using to display this text? – Kenster Jul 30 '14 at 13:21
  • I am trying to develop a terminal emulator like SSH Secure Shell or PuTTY. I want to display the output of the "more" command without the terminal escape sequences in JtextArea component. Can you suggest something? – Jhamb Jul 30 '14 at 14:39

2 Answers2

3

I found out the answer. Just one line of code does the trick.

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

Adding the above line before the connect() removes all the non printable characters.

Jhamb
  • 31
  • 4
0

If you are developing a terminal emulator you can consider using a third-party library that could help you to manage the input data flow, specially dealing with the ANSI terminal control characters you are encountering. Tools like Expect are traditionally used to automate interacting between a program and text based terminal systems.

There are several exiting Expect for Java implementations you can use. Here I'd like to promote my own open source tool called ExpectIt. It supports filtering the input data to remove unwanted characters like terminal control that you may find very useful for your use case. It has other advantages stated on the project page.

Here is an example of using ExpectIt to iterate through the results of the more command. Note registering the removeColors filter which filters out the terminal characters.

    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(" ");
        }

The code below works assuming that the corresponding methods are imported statically.

Alexey Gavrilov
  • 10,593
  • 2
  • 38
  • 48
  • I have never used Expect API before. So, I am naive to the Expect library. Can you please tell how to use it for "more" command? Thanks in advance :) – Jhamb Aug 11 '14 at 07:16
  • @Jhamb I have updated my answer with an example of "more" command. – Alexey Gavrilov Aug 11 '14 at 08:49
  • Thanks a lot ! :) But still some unwanted characters are getting printed like [?7h[?1l(B=ent (0%)[24;1 Is there a way to remove such characters. Thanks in advance ! – Jhamb Aug 12 '14 at 05:09
  • @Jhamb you can try with "removeNonPrintable" filter. If it does not help then you can write your own based on a regular expression. Refer to this page: https://github.com/Alexey1Gavrilov/ExpectIt#filtering-the-input – Alexey Gavrilov Aug 12 '14 at 06:50
  • What's the difference between the replaceInBuffer and replaceInString filters in ExpectIt? – golimar Oct 14 '19 at 13:11