SlideShare a Scribd company logo
1 of 5
Download to read offline
Adding Progress Bars to Your Scripts                                                                                                        http://oreilly.com/pub/h/943




                                                                                                                           Sign In/My Account | View Cart
                                                                                     Press
         Book List Learning Lab       PDFs       O'Reilly GearNewsletters                        Jobs
                                                                                     Room

                                                                                                                                             Buy the book!



                                   HACK       Adding Progress Bars to Your Scripts
                                              Give a visual indication that a download is progressing smoothly
                                   #18        The Code
                                              [Discuss (3) | Link to this hack]

                                  With all this downloading, it's often helpful to have some visual representation of its progress. In       By Kevin Hemenway,
                                  most of the scripts in this book, there's always a bit of visual information being displayed to the        Tara Calishain
                                  screen: that we're starting this URL here, processing this data there, and so on. These helpful bits       October 2003
                                  usually come before or after the actual data has been downloaded. But what if we want visual               More Info
                                  feedback while we're in the middle of a large MP3, movie, or database leech?

                                  If you're using a fairly recent vintage of the LWP library, you'll be able to interject your own subroutine to run at regular
                                  intervals during download. In this hack, we'll show you four different ways of adding various types of progress bars to
                                  your current applications. To get the most from this hack, you should have ready a URL that's roughly 500 KB or larger;
                                  it'll give you a good chance to see the progress bar in action.

                                  The Code

                                  The first progress bar is the simplest, providing only a visual heartbeat so that you can be sure things are progressing and
                                  not just hanging. Save the following code to a file called progress_bar.pl and run it from the command line as perl
                                  scriptnameURL, where URL is the online location of your appropriately large piece of sample data:

                                         #!/usr/bin/perl -w
                                         #
                                         # Progress Bar: Dots - Simple example of an LWP progress bar.
                                         # http://disobey.com/d/code/ or contact morbus@disobey.com.
                                         #
                                         # This code is free software; you can redistribute it and/or
                                         # modify it under the same terms as Perl itself.
                                         #

                                         use strict; $|++;
                                         my $VERSION = "1.0";

                                         # make sure we have the modules we need, else die peacefully.
                                         eval("use LWP 5.6.9;"); die "[err] LWP 5.6.9 or greater required.n" if $@;

                                         # now, check for passed URLs for downloading.
                                         die "[err] No URLs were passed for processing.n" unless @ARGV;

                                         # our downloaded data.
                                         my $final_data = undef;

                                         # loop through each URL.
                                         foreach my $url (@ARGV) {
                                            print "Downloading URL at ", substr($url, 0, 40), "... ";

                                              # create a new useragent and download the actual URL.
                                              # all the data gets thrown into $final_data, which
                                              # the callback subroutine appends to.
                                              my $ua = LWP::UserAgent->new( );
                                              my $response = $ua->get($url, ':content_cb' => &callback, );
                                              print "n"; # after the final dot from downloading.
                                         }

                                         # per chunk.
                                         sub callback {
                                            my ($data, $response, $protocol) = @_;
                                            $final_data .= $data;
                                            print ".";
                                         }

                                  None of this code is particularly new, save the addition of our primitive progress bar. We use LWP's standard get method,
                                  but add the :content_cb header with a value that is a reference to a subroutine that will be called at regular intervals as
                                  our content is downloaded. These intervals can be suggested with an optional :read_size_hint, which is the number
                                  of bytes you'd like received before they're passed to the callback.




1 di 5                                                                                                                                                   20/06/2009 11.56
Adding Progress Bars to Your Scripts                                                                                                           http://oreilly.com/pub/h/943


         Search                    In this example, we've defined that the data should be sent to a subroutine named callback. You'll notice that the
                              Go   routine receives the actual content, $data, that has been downloaded. Since we're overriding LWP's normal
                                   $response->content or :content_file features, we now have to take full control of the data. In this hack, we
          Hacks Site               store all our results in $final_data, but we don't actually do anything with them.
          • List of Titles
          • Got a Hack?            Most relevant, however, is the print statement within the callback routine. This is our first pathetic attempt at visual
          • Suggestion Box         feedback during the downloading process: every time a chunk of data gets sent our way, we spit out a dot. If the total data
                                   size is sufficiently large, our screen will be filled with dots, dots, and more dots:
         Resource Centers
         Bioinformatics
                                          Downloading URL at http://disobey.com/large_file.mov...
         C/C++                            ..........................................................................
         Databases                        ..........................................................................
         Digital Media                    ..........................................................................
         Enterprise Development           ..........................................................................
         Game Development                 ..........................................................................
         Java                             .....................................................................
         Linux/Unix
         Macintosh/OS X            While useful, it's certainly not very pretty, and it can be especially disruptive for large files (the previous example is the
         .NET                      output of downloading just 700 KB). Instead, how about we use a little primitive animation?
         Open Source
         Oracle                    If you've worked in the shell or installed various programs (or even a retail version of Linux), you may have seen rotating
         Perl                      cursors built from ASCII letters. These cursors could start at , erase that character, draw a |, erase, /, erase, -, and then
         Python                     to restart the loop. Individually, and without the benefit of a flipbook, these look pretty boring. Onscreen, however, they
         Scripting
                                   create a decent equivalent to an hourglass or spinning ball.
         Security
         Software Development
                                   Modify the previous script, adding the highlighted lines:
         SysAdmin/Networking
         Web
                                          ...
         Web Services
                                          # our downloaded data.
         Windows
                                          my $final_data = undef;
         Wireless
         XML
                                          # your animation and counter.
                                          my $counter; my @animation = qw(  | / - );
         Book Series
         Annoyances                       # loop through each URL.
         CD Bookshelves                   foreach my $url (@ARGV)
         Cookbooks                        ...
         Developer's Notebooks
         Hacks                     This initializes a counter and creates an array that contains the frames of our animations. As you can see, we use the same
         Head First                frames we discussed earlier. If you don't like `em, customize your own (perhaps . i l i). The last change we need to
         In A Nutshell             make is in our callback routine. Swap out the existing print "." with:
         Missing Manuals
         Pocket References                print "$animation[$counter++]b";
         Personal Trainer                 $counter = 0 if $counter == scalar(@animation);
         Technology & Society
                                   And that's it. For each chunk of data we receive, the next frame of the animation will play. When our counter is the same
         Publishing Partners
                                   as the number of frames, we reset and begin anew. Obviously, we can't show a readily apparent example of what this looks
         Mandriva
         No Starch Press
                                   like, so try it at your leisure.
         Paraglyph Press
         PC Publishing
                                   We can still do better, though. We've certainly removed the distracting dot distortion, but we're still left with only simple
         Pragmatic Bookshelf       output; we don't have raw information on how far we've gone and how far still to go. The following code provides a
         SitePoint                 progress meter with a visual percentage bar, as well as a numerical reading:
         Syngress Publishing



         Online Publications
         LinuxDevCenter.com
         MacDevCenter.com
         ONJava.com
         ONLamp.com
         OpenP2P.com
         Perl.com
         WebServices.XML.com
         WindowsDevCenter.com
         XML.com



         Special Interest
         Beta Chapters
         Events
         From the Editors List
         Letters
         MAKE
         Open Books
         tim.oreilly.com

         Special Sales
         Academic
         Corporate Services
         Government

         Inside O'Reilly




2 di 5                                                                                                                                                      20/06/2009 11.56
Adding Progress Bars to Your Scripts                                                                                                    http://oreilly.com/pub/h/943


         About O'Reilly
         Bookstores                    #!/usr/bin/perl -w
         Contact Us                    #
         International                 # Progress Bar: Wget - Wget style progress bar with LWP.
         Register Your Book            # http://disobey.com/d/code/ or contact morbus@disobey.com.
         User Groups                   # Original routine by tachyon at http://tachyon.perlmonk.org/
         Writing for O'Reilly          #
                                       # This code is free software; you can redistribute it and/or
                                       # modify it under the same terms as Perl itself.
                                       #

                                       use strict; $|++;
                                       my $VERSION = "1.0";

                                       # make sure we have the modules we need, else die peacefully.
                                       eval("use LWP 5.6.9;"); die "[err] LWP 5.6.9 or greater required.n" if $@;

                                       # now, check for passed URLs for downloading.
                                       die "[err] No URLs were passed for processing.n" unless @ARGV;

                                       # happy golucky variables.
                                       my $final_data; # our downloaded data.
                                       my $total_size; # total size of the URL.

                                       # loop through each URL.
                                       foreach my $url (@ARGV) {
                                          print "Downloading URL at ", substr($url, 0, 40), "...n";

                                           # create a new useragent and download the actual URL.
                                           # all the data gets thrown into $final_data, which
                                           # the callback subroutine appends to. before that,
                                           # though, get the total size of the URL in question.
                                           my $ua = LWP::UserAgent->new( );
                                           my $result = $ua->head($url);
                                           my $remote_headers = $result->headers;
                                           $total_size = $remote_headers->content_length;

                                           # now do the downloading.
                                           my $response = $ua->get($url, ':content_cb' => &callback );
                                       }

                                       # per chunk.
                                       sub callback {
                                          my ($data, $response, $protocol) = @_;
                                          $final_data .= $data;
                                          print progress_bar( length($final_data), $total_size, 25, '=' );
                                       }

                                       # wget-style. routine by tachyon
                                       # at http://tachyon.perlmonk.org/
                                       sub progress_bar {
                                           my ( $got, $total, $width, $char ) = @_;
                                           $width ||= 25; $char ||= '=';
                                           my $num_width = length $total;
                                           sprintf "|%-${width}s| Got %${num_width}s bytes of %s (%.2f%%)r",
                                               $char x (($width-1)*$got/$total). '>',
                                               $got, $total, 100*$got/+$total;
                                       }

                                You'll notice right off the bat that we've added another subroutine at the bottom of our code. Before we get into that, check
                                out our actual LWP request. Instead of just asking for the data, we first check the HTTP headers to see the size of the file
                                we'll be downloading. We store this size in a $total_size variable. It plays an important part in our new subroutine,
                                best demonstrated with a sample:

                                       Downloading URL at http://disobey.com/large_file.mov...
                                       |=============>          | Got 422452 bytes of 689368 (61.28%)

                                This is sprintf magic at work, thanks to a little magic from tachyon over at Perl Monks
                                (http://www.perlmonks.org/index.pl?node_id=80749). As each chunk of data gets sent to our callback, the display is
                                updated both as a bar and as a byte count and percentage. It's a wonderful piece of work and my preferred progress bar as
                                of this writing. As you can see in the progress_bar line of the callback, you can modify the width as well as the
                                character.

                                So far, we've rolled our own, but there is a module on CPAN, Term::ProgressBar
                                (http://search.cpan.org/author/FLUFFY/Term-ProgressBar), that takes care of the lion's share of the work for us. It has a
                                bit more functionality than sprintf, such as titling the progress bar, including an ETA, and growing to the length of the
                                user's terminal width. Here it is in action:




3 di 5                                                                                                                                               20/06/2009 11.56
Adding Progress Bars to Your Scripts                                                                      http://oreilly.com/pub/h/943



                                       #!/usr/bin/perl -w
                                       #
                                       # Progress Bar: Term::ProgressBar - progress bar with LWP.
                                       # http://disobey.com/d/code/ or contact morbus@disobey.com.
                                       # Original routine by tachyon at http://tachyon.perlmonk.org/
                                       #
                                       # This code is free software; you can redistribute it and/or
                                       # modify it under the same terms as Perl itself.
                                       #

                                       use strict; $|++;
                                       my $VERSION = "1.0";

                                       # make sure we have the modules we need, else die peacefully.
                                       eval("use LWP 5.6.9;");
                                       die "[err] LWP is not the required version.n" if $@;
                                       eval("use Term::ProgressBar;"); # prevent word-wrapping.
                                       die "[err] Term::ProgressBar not installed.n" if $@;

                                       # now, check for passed URLs for downloading.
                                       die "[err] No URLs were passed for processing.n" unless @ARGV;


                                       # happy golucky variables.
                                       my $final_data = 0; # our downloaded data.
                                       my $total_size;      # total size of the URL.
                                       my $progress;        # progress bar object.
                                       my $next_update = 0; # reduce ProgressBar use.

                                       # loop through each URL.
                                       foreach my $url (@ARGV) {
                                          print "Downloading URL at ", substr($url, 0, 40), "...n";

                                           # create a new useragent and download the actual URL.
                                           # all the data gets thrown into $final_data, which
                                           # the callback subroutine appends to. before that,
                                           # though, get the total size of the URL in question.
                                           my $ua = LWP::UserAgent->new( );
                                           my $result = $ua->head($url);
                                           my $remote_headers = $result->headers;
                                           $total_size = $remote_headers->content_length;

                                          # initialize our progress bar.
                                          $progress = Term::ProgressBar->new({count => $total_size, ETA => &return;
                                       'linear'});
                                          $progress->minor(0);           # turns off the floating asterisks.
                                          $progress->max_update_rate(1); # only relevant when ETA is used.

                                           # now do the downloading.
                                           my $response = $ua->get($url, ':content_cb' => &callback );

                                           # top off the progress bar.
                                           $progress->update($total_size);
                                       }

                                       # per chunk.
                                       sub callback {
                                          my ($data, $response, $protocol) = @_;
                                          $final_data .= $data;

                                           # reduce usage, as per example 3 in POD.
                                           $next_update = $progress->update(length($final_data))if length($final_data) >= $ne
                                       }

                               And here's its output:

                                       Downloading URL at http://disobey.com/large_file.mov...
                                        13% [========                                        ]9m57s Left

                               More examples are available in the Term::ProgressBar documentation.



                                Comment on this hack
                                You must be logged in to the O'Reilly Network to post a comment.

                                                                      Showing
                               messages 1 through 3 of 3.

                                   Warning
                                   2005-11-06 04:02:02 tiberido [Reply | View]




4 di 5                                                                                                              20/06/2009 11.56
Adding Progress Bars to Your Scripts                                                                                                          http://oreilly.com/pub/h/943



                                   I got an

                                   Undefined subroutine &main::return called at ScriptProgBar.pl line 44.

                                   In the last script (Term::ProgressBar). I deleted &return

                                   $progress = Term::ProgressBar->new({count => $total_size, ETA => 'linear'});

                                   An now the script works fine.

                                   Best regards,

                                   Tiberido


                                   Net::FTP Progress Bar
                                   2005-07-20 14:22:52 E=Mc² [Reply | View]

                                   Anyway of adding this to and ftp get? or is there any other way to add a progress bar to an ftp get you can
                                   use the ftp->size but I cant seem to get the display to update as I cant apend per bytes any help or
                                   suggestions

                                   Term::ProgressBar
                                   2005-01-28 21:50:28 kiwiberryfox [Reply | View]

                                          I was going through the codes for different Progress bars and I noticed
                                          a typo in the last Progress bar code for
                                          href="http://hacks.oreilly.com/pub/h/943">Term::ProgressBar. Line 45


                                   <hr />

                                   # initialize our progress bar.
                                   $progress = Term::ProgressBar->new({count => $total_size, ETA => &return;
                                   'linear'});
                                   $progress->minor(0);

                                   <hr />
                                   You should replace the semicolon with a comma.
                                   <hr />
                                   # initialize our progress bar.
                                   $progress = Term::ProgressBar->new({count => $total_size, ETA => &return,
                                   'linear'});
                                   $progress->minor(0);

                                   Thanks,
                                   Kiwiberryfox


                               Showing messages 1 through 3 of 3.




                                                                                O'Reilly Home | Privacy Policy
                                                                                © 2007 O'Reilly Media, Inc.
                                          Website: webmaster@oreilly.com | Customer Service: orders@oreilly.com | Book issues: booktech@oreilly.com

                                          All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners.




5 di 5                                                                                                                                                     20/06/2009 11.56

More Related Content

What's hot

Generating Linked Data descriptions of Debian packages in the Debian PTS
Generating Linked Data descriptions of Debian packages in the Debian PTSGenerating Linked Data descriptions of Debian packages in the Debian PTS
Generating Linked Data descriptions of Debian packages in the Debian PTSolberger
 
Confitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Confitura 2018 — Apache Beam — Promyk Nadziei Data EngineeraConfitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Confitura 2018 — Apache Beam — Promyk Nadziei Data EngineeraPiotr Wikiel
 
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...Chris Fregly
 
DSpace Manual for BALID Trainee
DSpace Manual for BALID Trainee DSpace Manual for BALID Trainee
DSpace Manual for BALID Trainee Nur Ahammad
 
Puppet getting started by Dirk Götz
Puppet getting started by Dirk GötzPuppet getting started by Dirk Götz
Puppet getting started by Dirk GötzNETWAYS
 
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...Chris Fregly
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spackinside-BigData.com
 
Fluentd - road to v1 -
Fluentd - road to v1 -Fluentd - road to v1 -
Fluentd - road to v1 -N Masahiro
 
Be a better developer with Docker (revision 3)
Be a better developer with Docker (revision 3)Be a better developer with Docker (revision 3)
Be a better developer with Docker (revision 3)Nicola Paolucci
 
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHPHands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHPDana Luther
 
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...Chris Fregly
 
Nvidia GPU Tech Conference - Optimizing, Profiling, and Deploying TensorFlow...
Nvidia GPU Tech Conference -  Optimizing, Profiling, and Deploying TensorFlow...Nvidia GPU Tech Conference -  Optimizing, Profiling, and Deploying TensorFlow...
Nvidia GPU Tech Conference - Optimizing, Profiling, and Deploying TensorFlow...Chris Fregly
 
Auto Deploy Deep Dive – vBrownBag Style
Auto Deploy Deep Dive – vBrownBag StyleAuto Deploy Deep Dive – vBrownBag Style
Auto Deploy Deep Dive – vBrownBag StyleRobert Nelson
 
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...Chris Fregly
 
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...Amazon Web Services
 
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...Chris Fregly
 
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...Chris Fregly
 
DSpace: Technical Basics
DSpace: Technical BasicsDSpace: Technical Basics
DSpace: Technical BasicsIryna Kuchma
 
Apache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppApache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppJim Jagielski
 
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...Chris Fregly
 

What's hot (20)

Generating Linked Data descriptions of Debian packages in the Debian PTS
Generating Linked Data descriptions of Debian packages in the Debian PTSGenerating Linked Data descriptions of Debian packages in the Debian PTS
Generating Linked Data descriptions of Debian packages in the Debian PTS
 
Confitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Confitura 2018 — Apache Beam — Promyk Nadziei Data EngineeraConfitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
Confitura 2018 — Apache Beam — Promyk Nadziei Data Engineera
 
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...
PipelineAI Optimizes Your Enterprise AI Pipeline from Distributed Training to...
 
DSpace Manual for BALID Trainee
DSpace Manual for BALID Trainee DSpace Manual for BALID Trainee
DSpace Manual for BALID Trainee
 
Puppet getting started by Dirk Götz
Puppet getting started by Dirk GötzPuppet getting started by Dirk Götz
Puppet getting started by Dirk Götz
 
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...
PipelineAI + TensorFlow AI + Spark ML + Kuberenetes + Istio + AWS SageMaker +...
 
Binary Packaging for HPC with Spack
Binary Packaging for HPC with SpackBinary Packaging for HPC with Spack
Binary Packaging for HPC with Spack
 
Fluentd - road to v1 -
Fluentd - road to v1 -Fluentd - road to v1 -
Fluentd - road to v1 -
 
Be a better developer with Docker (revision 3)
Be a better developer with Docker (revision 3)Be a better developer with Docker (revision 3)
Be a better developer with Docker (revision 3)
 
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHPHands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
 
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...
Hyper-Parameter Tuning Across the Entire AI Pipeline GPU Tech Conference San ...
 
Nvidia GPU Tech Conference - Optimizing, Profiling, and Deploying TensorFlow...
Nvidia GPU Tech Conference -  Optimizing, Profiling, and Deploying TensorFlow...Nvidia GPU Tech Conference -  Optimizing, Profiling, and Deploying TensorFlow...
Nvidia GPU Tech Conference - Optimizing, Profiling, and Deploying TensorFlow...
 
Auto Deploy Deep Dive – vBrownBag Style
Auto Deploy Deep Dive – vBrownBag StyleAuto Deploy Deep Dive – vBrownBag Style
Auto Deploy Deep Dive – vBrownBag Style
 
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...
High Performance Distributed TensorFlow with GPUs - TensorFlow Chicago Meetup...
 
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...
Dynamic Content Acceleration: Lightning Fast Web Apps with Amazon CloudFront ...
 
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...
High Performance Distributed TensorFlow in Production with GPUs - NIPS 2017 -...
 
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...
Building Google Cloud ML Engine From Scratch on AWS with PipelineAI - ODSC Lo...
 
DSpace: Technical Basics
DSpace: Technical BasicsDSpace: Technical Basics
DSpace: Technical Basics
 
Apache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer AppApache httpd 2.4: The Cloud Killer App
Apache httpd 2.4: The Cloud Killer App
 
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
High Performance TensorFlow in Production - Big Data Spain - Madrid - Nov 15 ...
 

Viewers also liked

International Overview &amp; Future Medical Devices Regulations
International Overview &amp; Future   Medical Devices RegulationsInternational Overview &amp; Future   Medical Devices Regulations
International Overview &amp; Future Medical Devices Regulationsmdbio2009
 
Hoe iwt subsidie aanvragen
Hoe iwt subsidie aanvragenHoe iwt subsidie aanvragen
Hoe iwt subsidie aanvragenHans Haagdorens
 
Interior Redesign Before & After Photos
Interior Redesign Before & After PhotosInterior Redesign Before & After Photos
Interior Redesign Before & After PhotosHomescapes
 
Tips & trics voor innovatieve starters (ppt startersdag Unizo)
 Tips & trics voor innovatieve starters (ppt startersdag Unizo) Tips & trics voor innovatieve starters (ppt startersdag Unizo)
Tips & trics voor innovatieve starters (ppt startersdag Unizo)Hans Haagdorens
 

Viewers also liked (6)

International Overview &amp; Future Medical Devices Regulations
International Overview &amp; Future   Medical Devices RegulationsInternational Overview &amp; Future   Medical Devices Regulations
International Overview &amp; Future Medical Devices Regulations
 
Astronomy
AstronomyAstronomy
Astronomy
 
Hoe iwt subsidie aanvragen
Hoe iwt subsidie aanvragenHoe iwt subsidie aanvragen
Hoe iwt subsidie aanvragen
 
Interior Redesign Before & After Photos
Interior Redesign Before & After PhotosInterior Redesign Before & After Photos
Interior Redesign Before & After Photos
 
J Ivy Portfolio
J Ivy PortfolioJ Ivy Portfolio
J Ivy Portfolio
 
Tips & trics voor innovatieve starters (ppt startersdag Unizo)
 Tips & trics voor innovatieve starters (ppt startersdag Unizo) Tips & trics voor innovatieve starters (ppt startersdag Unizo)
Tips & trics voor innovatieve starters (ppt startersdag Unizo)
 

Similar to progress

How to Upgrade Your Database Plan on Heroku and Rails Setup?
How to Upgrade Your Database Plan on Heroku and Rails Setup?How to Upgrade Your Database Plan on Heroku and Rails Setup?
How to Upgrade Your Database Plan on Heroku and Rails Setup?Katy Slemon
 
Symfony finally swiped right on envvars
Symfony finally swiped right on envvarsSymfony finally swiped right on envvars
Symfony finally swiped right on envvarsSam Marley-Jarrett
 
A DevOps guide to Kubernetes
A DevOps guide to KubernetesA DevOps guide to Kubernetes
A DevOps guide to KubernetesPaul Czarkowski
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809Tim Bunce
 
Top laravel packages to install handpicked list from expert
Top laravel packages to install handpicked list from expertTop laravel packages to install handpicked list from expert
Top laravel packages to install handpicked list from expertKaty Slemon
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012Carlos Sanchez
 
Packaging for the Maemo Platform
Packaging for the Maemo PlatformPackaging for the Maemo Platform
Packaging for the Maemo PlatformJeremiah Foster
 
Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureMichaël Lopez
 
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014gethue
 
Omaha (Google Update) server
Omaha (Google Update) serverOmaha (Google Update) server
Omaha (Google Update) serverDmitry Lyfar
 
How to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysisHow to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysisTiago Simões
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...Alexander Dean
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principlesPerl Careers
 
Liquibase - Open Source version control for your database
Liquibase - Open Source version control for your databaseLiquibase - Open Source version control for your database
Liquibase - Open Source version control for your databaseBlaine Carter
 
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...Shirshanka Das
 

Similar to progress (20)

How to Upgrade Your Database Plan on Heroku and Rails Setup?
How to Upgrade Your Database Plan on Heroku and Rails Setup?How to Upgrade Your Database Plan on Heroku and Rails Setup?
How to Upgrade Your Database Plan on Heroku and Rails Setup?
 
Lumen
LumenLumen
Lumen
 
Symfony finally swiped right on envvars
Symfony finally swiped right on envvarsSymfony finally swiped right on envvars
Symfony finally swiped right on envvars
 
A DevOps guide to Kubernetes
A DevOps guide to KubernetesA DevOps guide to Kubernetes
A DevOps guide to Kubernetes
 
DBD::Gofer 200809
DBD::Gofer 200809DBD::Gofer 200809
DBD::Gofer 200809
 
Top laravel packages to install handpicked list from expert
Top laravel packages to install handpicked list from expertTop laravel packages to install handpicked list from expert
Top laravel packages to install handpicked list from expert
 
From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012From Dev to DevOps - Codemotion ES 2012
From Dev to DevOps - Codemotion ES 2012
 
Packaging for the Maemo Platform
Packaging for the Maemo PlatformPackaging for the Maemo Platform
Packaging for the Maemo Platform
 
Chef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructureChef - industrialize and automate your infrastructure
Chef - industrialize and automate your infrastructure
 
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014
Hue: Big Data Web applications for Interactive Hadoop at Big Data Spain 2014
 
Omaha (Google Update) server
Omaha (Google Update) serverOmaha (Google Update) server
Omaha (Google Update) server
 
How to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysisHow to create a multi tenancy for an interactive data analysis
How to create a multi tenancy for an interactive data analysis
 
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
From Zero to Hadoop: a tutorial for getting started writing Hadoop jobs on Am...
 
Os Bunce
Os BunceOs Bunce
Os Bunce
 
CakePHP
CakePHPCakePHP
CakePHP
 
PSGI and Plack from first principles
PSGI and Plack from first principlesPSGI and Plack from first principles
PSGI and Plack from first principles
 
Liquibase - Open Source version control for your database
Liquibase - Open Source version control for your databaseLiquibase - Open Source version control for your database
Liquibase - Open Source version control for your database
 
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...
Apache Gobblin: Bridging Batch and Streaming Data Integration. Big Data Meetu...
 
Pecl Picks
Pecl PicksPecl Picks
Pecl Picks
 
Pentest and Security Discussion
Pentest and Security DiscussionPentest and Security Discussion
Pentest and Security Discussion
 

Recently uploaded

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfPrecisely
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.Curtis Poe
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Commit University
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 3652toLead Limited
 

Recently uploaded (20)

Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdfHyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
Hyperautomation and AI/ML: A Strategy for Digital Transformation Success.pdf
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.How AI, OpenAI, and ChatGPT impact business and software.
How AI, OpenAI, and ChatGPT impact business and software.
 
Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!Nell’iperspazio con Rocket: il Framework Web di Rust!
Nell’iperspazio con Rocket: il Framework Web di Rust!
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365Ensuring Technical Readiness For Copilot in Microsoft 365
Ensuring Technical Readiness For Copilot in Microsoft 365
 

progress

  • 1. Adding Progress Bars to Your Scripts http://oreilly.com/pub/h/943 Sign In/My Account | View Cart Press Book List Learning Lab PDFs O'Reilly GearNewsletters Jobs Room Buy the book! HACK Adding Progress Bars to Your Scripts Give a visual indication that a download is progressing smoothly #18 The Code [Discuss (3) | Link to this hack] With all this downloading, it's often helpful to have some visual representation of its progress. In By Kevin Hemenway, most of the scripts in this book, there's always a bit of visual information being displayed to the Tara Calishain screen: that we're starting this URL here, processing this data there, and so on. These helpful bits October 2003 usually come before or after the actual data has been downloaded. But what if we want visual More Info feedback while we're in the middle of a large MP3, movie, or database leech? If you're using a fairly recent vintage of the LWP library, you'll be able to interject your own subroutine to run at regular intervals during download. In this hack, we'll show you four different ways of adding various types of progress bars to your current applications. To get the most from this hack, you should have ready a URL that's roughly 500 KB or larger; it'll give you a good chance to see the progress bar in action. The Code The first progress bar is the simplest, providing only a visual heartbeat so that you can be sure things are progressing and not just hanging. Save the following code to a file called progress_bar.pl and run it from the command line as perl scriptnameURL, where URL is the online location of your appropriately large piece of sample data: #!/usr/bin/perl -w # # Progress Bar: Dots - Simple example of an LWP progress bar. # http://disobey.com/d/code/ or contact morbus@disobey.com. # # This code is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # use strict; $|++; my $VERSION = "1.0"; # make sure we have the modules we need, else die peacefully. eval("use LWP 5.6.9;"); die "[err] LWP 5.6.9 or greater required.n" if $@; # now, check for passed URLs for downloading. die "[err] No URLs were passed for processing.n" unless @ARGV; # our downloaded data. my $final_data = undef; # loop through each URL. foreach my $url (@ARGV) { print "Downloading URL at ", substr($url, 0, 40), "... "; # create a new useragent and download the actual URL. # all the data gets thrown into $final_data, which # the callback subroutine appends to. my $ua = LWP::UserAgent->new( ); my $response = $ua->get($url, ':content_cb' => &callback, ); print "n"; # after the final dot from downloading. } # per chunk. sub callback { my ($data, $response, $protocol) = @_; $final_data .= $data; print "."; } None of this code is particularly new, save the addition of our primitive progress bar. We use LWP's standard get method, but add the :content_cb header with a value that is a reference to a subroutine that will be called at regular intervals as our content is downloaded. These intervals can be suggested with an optional :read_size_hint, which is the number of bytes you'd like received before they're passed to the callback. 1 di 5 20/06/2009 11.56
  • 2. Adding Progress Bars to Your Scripts http://oreilly.com/pub/h/943 Search In this example, we've defined that the data should be sent to a subroutine named callback. You'll notice that the Go routine receives the actual content, $data, that has been downloaded. Since we're overriding LWP's normal $response->content or :content_file features, we now have to take full control of the data. In this hack, we Hacks Site store all our results in $final_data, but we don't actually do anything with them. • List of Titles • Got a Hack? Most relevant, however, is the print statement within the callback routine. This is our first pathetic attempt at visual • Suggestion Box feedback during the downloading process: every time a chunk of data gets sent our way, we spit out a dot. If the total data size is sufficiently large, our screen will be filled with dots, dots, and more dots: Resource Centers Bioinformatics Downloading URL at http://disobey.com/large_file.mov... C/C++ .......................................................................... Databases .......................................................................... Digital Media .......................................................................... Enterprise Development .......................................................................... Game Development .......................................................................... Java ..................................................................... Linux/Unix Macintosh/OS X While useful, it's certainly not very pretty, and it can be especially disruptive for large files (the previous example is the .NET output of downloading just 700 KB). Instead, how about we use a little primitive animation? Open Source Oracle If you've worked in the shell or installed various programs (or even a retail version of Linux), you may have seen rotating Perl cursors built from ASCII letters. These cursors could start at , erase that character, draw a |, erase, /, erase, -, and then Python to restart the loop. Individually, and without the benefit of a flipbook, these look pretty boring. Onscreen, however, they Scripting create a decent equivalent to an hourglass or spinning ball. Security Software Development Modify the previous script, adding the highlighted lines: SysAdmin/Networking Web ... Web Services # our downloaded data. Windows my $final_data = undef; Wireless XML # your animation and counter. my $counter; my @animation = qw( | / - ); Book Series Annoyances # loop through each URL. CD Bookshelves foreach my $url (@ARGV) Cookbooks ... Developer's Notebooks Hacks This initializes a counter and creates an array that contains the frames of our animations. As you can see, we use the same Head First frames we discussed earlier. If you don't like `em, customize your own (perhaps . i l i). The last change we need to In A Nutshell make is in our callback routine. Swap out the existing print "." with: Missing Manuals Pocket References print "$animation[$counter++]b"; Personal Trainer $counter = 0 if $counter == scalar(@animation); Technology & Society And that's it. For each chunk of data we receive, the next frame of the animation will play. When our counter is the same Publishing Partners as the number of frames, we reset and begin anew. Obviously, we can't show a readily apparent example of what this looks Mandriva No Starch Press like, so try it at your leisure. Paraglyph Press PC Publishing We can still do better, though. We've certainly removed the distracting dot distortion, but we're still left with only simple Pragmatic Bookshelf output; we don't have raw information on how far we've gone and how far still to go. The following code provides a SitePoint progress meter with a visual percentage bar, as well as a numerical reading: Syngress Publishing Online Publications LinuxDevCenter.com MacDevCenter.com ONJava.com ONLamp.com OpenP2P.com Perl.com WebServices.XML.com WindowsDevCenter.com XML.com Special Interest Beta Chapters Events From the Editors List Letters MAKE Open Books tim.oreilly.com Special Sales Academic Corporate Services Government Inside O'Reilly 2 di 5 20/06/2009 11.56
  • 3. Adding Progress Bars to Your Scripts http://oreilly.com/pub/h/943 About O'Reilly Bookstores #!/usr/bin/perl -w Contact Us # International # Progress Bar: Wget - Wget style progress bar with LWP. Register Your Book # http://disobey.com/d/code/ or contact morbus@disobey.com. User Groups # Original routine by tachyon at http://tachyon.perlmonk.org/ Writing for O'Reilly # # This code is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # use strict; $|++; my $VERSION = "1.0"; # make sure we have the modules we need, else die peacefully. eval("use LWP 5.6.9;"); die "[err] LWP 5.6.9 or greater required.n" if $@; # now, check for passed URLs for downloading. die "[err] No URLs were passed for processing.n" unless @ARGV; # happy golucky variables. my $final_data; # our downloaded data. my $total_size; # total size of the URL. # loop through each URL. foreach my $url (@ARGV) { print "Downloading URL at ", substr($url, 0, 40), "...n"; # create a new useragent and download the actual URL. # all the data gets thrown into $final_data, which # the callback subroutine appends to. before that, # though, get the total size of the URL in question. my $ua = LWP::UserAgent->new( ); my $result = $ua->head($url); my $remote_headers = $result->headers; $total_size = $remote_headers->content_length; # now do the downloading. my $response = $ua->get($url, ':content_cb' => &callback ); } # per chunk. sub callback { my ($data, $response, $protocol) = @_; $final_data .= $data; print progress_bar( length($final_data), $total_size, 25, '=' ); } # wget-style. routine by tachyon # at http://tachyon.perlmonk.org/ sub progress_bar { my ( $got, $total, $width, $char ) = @_; $width ||= 25; $char ||= '='; my $num_width = length $total; sprintf "|%-${width}s| Got %${num_width}s bytes of %s (%.2f%%)r", $char x (($width-1)*$got/$total). '>', $got, $total, 100*$got/+$total; } You'll notice right off the bat that we've added another subroutine at the bottom of our code. Before we get into that, check out our actual LWP request. Instead of just asking for the data, we first check the HTTP headers to see the size of the file we'll be downloading. We store this size in a $total_size variable. It plays an important part in our new subroutine, best demonstrated with a sample: Downloading URL at http://disobey.com/large_file.mov... |=============> | Got 422452 bytes of 689368 (61.28%) This is sprintf magic at work, thanks to a little magic from tachyon over at Perl Monks (http://www.perlmonks.org/index.pl?node_id=80749). As each chunk of data gets sent to our callback, the display is updated both as a bar and as a byte count and percentage. It's a wonderful piece of work and my preferred progress bar as of this writing. As you can see in the progress_bar line of the callback, you can modify the width as well as the character. So far, we've rolled our own, but there is a module on CPAN, Term::ProgressBar (http://search.cpan.org/author/FLUFFY/Term-ProgressBar), that takes care of the lion's share of the work for us. It has a bit more functionality than sprintf, such as titling the progress bar, including an ETA, and growing to the length of the user's terminal width. Here it is in action: 3 di 5 20/06/2009 11.56
  • 4. Adding Progress Bars to Your Scripts http://oreilly.com/pub/h/943 #!/usr/bin/perl -w # # Progress Bar: Term::ProgressBar - progress bar with LWP. # http://disobey.com/d/code/ or contact morbus@disobey.com. # Original routine by tachyon at http://tachyon.perlmonk.org/ # # This code is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. # use strict; $|++; my $VERSION = "1.0"; # make sure we have the modules we need, else die peacefully. eval("use LWP 5.6.9;"); die "[err] LWP is not the required version.n" if $@; eval("use Term::ProgressBar;"); # prevent word-wrapping. die "[err] Term::ProgressBar not installed.n" if $@; # now, check for passed URLs for downloading. die "[err] No URLs were passed for processing.n" unless @ARGV; # happy golucky variables. my $final_data = 0; # our downloaded data. my $total_size; # total size of the URL. my $progress; # progress bar object. my $next_update = 0; # reduce ProgressBar use. # loop through each URL. foreach my $url (@ARGV) { print "Downloading URL at ", substr($url, 0, 40), "...n"; # create a new useragent and download the actual URL. # all the data gets thrown into $final_data, which # the callback subroutine appends to. before that, # though, get the total size of the URL in question. my $ua = LWP::UserAgent->new( ); my $result = $ua->head($url); my $remote_headers = $result->headers; $total_size = $remote_headers->content_length; # initialize our progress bar. $progress = Term::ProgressBar->new({count => $total_size, ETA => &return; 'linear'}); $progress->minor(0); # turns off the floating asterisks. $progress->max_update_rate(1); # only relevant when ETA is used. # now do the downloading. my $response = $ua->get($url, ':content_cb' => &callback ); # top off the progress bar. $progress->update($total_size); } # per chunk. sub callback { my ($data, $response, $protocol) = @_; $final_data .= $data; # reduce usage, as per example 3 in POD. $next_update = $progress->update(length($final_data))if length($final_data) >= $ne } And here's its output: Downloading URL at http://disobey.com/large_file.mov... 13% [======== ]9m57s Left More examples are available in the Term::ProgressBar documentation. Comment on this hack You must be logged in to the O'Reilly Network to post a comment. Showing messages 1 through 3 of 3. Warning 2005-11-06 04:02:02 tiberido [Reply | View] 4 di 5 20/06/2009 11.56
  • 5. Adding Progress Bars to Your Scripts http://oreilly.com/pub/h/943 I got an Undefined subroutine &main::return called at ScriptProgBar.pl line 44. In the last script (Term::ProgressBar). I deleted &return $progress = Term::ProgressBar->new({count => $total_size, ETA => 'linear'}); An now the script works fine. Best regards, Tiberido Net::FTP Progress Bar 2005-07-20 14:22:52 E=Mc² [Reply | View] Anyway of adding this to and ftp get? or is there any other way to add a progress bar to an ftp get you can use the ftp->size but I cant seem to get the display to update as I cant apend per bytes any help or suggestions Term::ProgressBar 2005-01-28 21:50:28 kiwiberryfox [Reply | View] I was going through the codes for different Progress bars and I noticed a typo in the last Progress bar code for href="http://hacks.oreilly.com/pub/h/943">Term::ProgressBar. Line 45 <hr /> # initialize our progress bar. $progress = Term::ProgressBar->new({count => $total_size, ETA => &return; 'linear'}); $progress->minor(0); <hr /> You should replace the semicolon with a comma. <hr /> # initialize our progress bar. $progress = Term::ProgressBar->new({count => $total_size, ETA => &return, 'linear'}); $progress->minor(0); Thanks, Kiwiberryfox Showing messages 1 through 3 of 3. O'Reilly Home | Privacy Policy © 2007 O'Reilly Media, Inc. Website: webmaster@oreilly.com | Customer Service: orders@oreilly.com | Book issues: booktech@oreilly.com All trademarks and registered trademarks appearing on oreilly.com are the property of their respective owners. 5 di 5 20/06/2009 11.56