Re: output of shell script in text view




On Jan 31, 2006, at 3:35 PM, Eisenknapp, Josef wrote:

My problem today is, that i want to show to output of a shellscript in a
Gtk2::Texview. To start the script i'm using the following.

        my $fh = new IO::Pipe;
        $fh->reader("./print_to_stdout.sh");

        my $helper_tag = Gtk2::Helper->add_watch(fileno $fh, 'in',sub{
            &watch_callback($fh)
            });

The script looks as follows:

        #!/bin/bash

        printf "bloedsinn !\n"
        sleep 1
        printf "GFIS_STATUS Eine Gui status Meldung 1\n"
        sleep 1
        printf "GFIS_STATUS Eine Gui status Meldung 1.6\n"
        sleep 1
        printf "GFIS_WARNING Eine Gui Warning Meldung 2\n"
        sleep 1
        echo "GFIS_STATUS Eine Gui status Meldung 3 "
        sleep 1
        echo "GFIS_WARNING Eine Gui Warning Meldung 4"
        #sleep 1
        echo "noch mehr bloedsinn !\n"
        echo
        echo "GFIS_STATUS Eine Gui status Meldung 5"
        #sleep 1
        echo "GFIS_WARNING Eine Gui Warning Meldung 6"
        #sleep 1
        echo "GFIS_STATUS Eine Gui status Meldung 7"
        #sleep 1
        echo "GFIS_WARNING Eine Gui Warning Meldung 8"
-------------------------------------------------------

The script will have more functionality than this example of course.
As you can see I tried to run the script with sleeps between the prints/echos and without them. When i run it with the sleep commands everything looks fine, but if i omit the sleeps, my callback is't called any more.

When you omit the sleeps, all of those lines show up at once, but your code doesn't handle either reading multiple lines or reading partial lines.

Here's an alternative implementation:

    my $spillover = '';  # for partial line reads.
    sub watch_callback{
        print "status callback called\n";
        my ($fh) = @_;

        my $line;
        $fh->sysread($line,1000);
        $spillover = '' if not defined $spillover;
        $line = $spillover . $line;
        $spillover = '';
        if ($line !~ m/\n$/s) {
            if ($line =~ s/([^\n]+)$//s) {
                $spillover = $1;
            }
        }
        local $_;
        foreach (split /\n/, $line) {
            if (s/^GFIS_STATUS\s+//){
                $status_buffer->insert_with_tags_by_name
($status_buffer->get_end_iter(), $_."\n", 'status');
            }
            elsif (s/^GFIS_WARNING\s+//) {
                $status_buffer->insert_with_tags_by_name
                        ($status_buffer->get_end_iter(),
                         "WARNING: $_\n", 'warning');
            }
            else{
                print "just a message\n";
            }
        }
        if (!$line && !$spillover) {
            1 while wait != -1 ;
            print "remove helper\n";
            Gtk2::Helper->remove_watch($helper_tag);
        }

        return TRUE;
    }


That works as expected for me.


-> And last: Is it possible to watch a file and run a callback everytime a line is appended to the file? I tried to do so with a Gtk2::Helper, but ended up with 100% CPU consumption becaus the callback was called everytime it was save to read the file.

tail(1) does this. I've never looked to see *how* it does it. You could use fam to monitor the file for changes, or just check the file size every so often, and read if the size has changed.




--
me: Need any help?
elysse, hugging the toilet: No thanks, i can puke just fine by myself.





[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]