EigenFunctions has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to use the open() pipe feature to make use of the progress bar feature of zenity and I can't seem to get it to work. I tried a shell script I found online and that worked so I know that zenity works (not surprisingly). Here is my code:

open(my $Progress, '|-', 'zenity --title "Explore" --progress --percen +tage 0 ' . '--text "Just a dumb test" --auto-close --aut +o-kill') or die "**Fatal err, open pipe writ +e failed"; #open(my $Progress, '|-', 'cat -n - >zippy.txt') or # die "**Fatal err, open pipe wri +te failed"; sleep 2; foreach my $Percent ( qw{10 20 30 40 50 60 70 80 90 100} ) { print "DBG> ", $Percent, "\n"; # print $Progress sprintf("%3d\n", $Percent); print $Progress "$Percent\n"; sleep 2; print $Progress "# Retry $Percent\n"; } close($Progress);

Notice the commented out code that I tried "cat" and it worked as expected. I also tried a different way to send the percent value and it failed as well.

When it runs, the zenity panel comes up with 0 percent with a "cancel" button and a grayed out "OK" button. The Perl program completes and the zenity panel disappears. I don't know what I'm doing wrong.

Can anyone help?

Thanks,
  EigenFunctions
  OpSys: Ubuntu 18.04; Perl: Perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi (with 67 registered patches)   OpSys: Win7 x64 Service Pack 1 Professional/Home Premium; Perl: Strawberry (v5.22.0)/ActiveState (v5.14.2)

Replies are listed 'Best First'.
Re: Linux Perl with zenity progress bar (updated)
by haukex (Archbishop) on Feb 11, 2021 at 20:32 UTC

    Turning on autoflush on the handle worked for me (IIRC, this may require a use IO::File; on old Perls, before 5.14). Also please note the advice in Calling External Commands More Safely!

    use warnings; use strict; open(my $Progress, '|-', qw/ zenity --title Explore --progress --percentage 0 --text Test --auto-close --auto-kill /) or die $!; $Progress->autoflush; foreach my $Percent ( qw{10 20 30 40 50 60 70 80 90 100} ) { sleep 2; print "DBG> ", $Percent, "\n"; print $Progress "$Percent\n"; print $Progress "# Test $Percent\n"; } close($Progress) or die $! ? $! : $?;

    Update: And here's a version that handles the user clicking the "Cancel" button, which apparently causes a SIGHUP.

    { my $run = 1; local $SIG{HUP} = sub { $run=0; }; open(my $Progress, '|-', qw/ zenity --title Explore --progress --percentage 0 --text Test --auto-close --auto-kill /) or die $!; $Progress->autoflush; print $Progress "# Test 0%\n"; foreach my $Percent ( qw{10 20 30 40 50 60 70 80 90 100} ) { sleep 1 if $run; unless ($run) { print "Canceled\n"; last } print "DBG> ", $Percent, "\n"; print $Progress "$Percent\n"; print $Progress "# Test $Percent%\n"; } close($Progress) or $run and die $! ? $! : $?; print "Done.\n"; }

    Update 2: Minor edits to second example.

      It worked! Thank-you!

      I didn't need $SIG{HUP} even with or without the zenity options: --auto-close --auto-kill

      Thanks again!

      Thanks,
        EigenFunctions
        OpSys: Ubuntu 18.04; Perl: Perl 5, version 26, subversion 1 (v5.26.1) built for x86_64-linux-gnu-thread-multi (with 71 registered patches)