Writing nicer console scripts

Recently I working on a web application for a client over at my new company, Spark Creek. The particular component I was building was an import script, runnable via the command line. It was written in PHP, as a bundle for Symfony. At first, I built the script to output progress like “Matched 50 URLs on page: 1”. It would output a newline for every page. This produced a lot of output for a simple console script, and wasn’t very nice. What I wanted to do was match certain utilities like wget, which have a progress indicator that changes dynamically. I looked and couldn’t find how to do it, but with a little research I was able to recreate the effect.

The \x08 hex character code is the ASCII backspace character. If you write it to the console, it deletes a character. With PHP, I kept track of the line length, and every iteration of the loop, I would use str_repeat to send however many backspace characters I needed to erase the current line. Then I would write a new line for the current progress of the loop. This created a very smooth progress indicator.

Here’s a barebones version as a proof of concept:

<?php
$lastLineSize = 0;

for ($i = 0; $i <= 50; $i++) {
    echo str_repeat("\x08", $lastLineSize);
    echo "Iteration {$i} of 50";
    $lastLineSize = strlen("Iteration {$i} of 50");
    usleep(100000);
}

echo " - Done\n";

and the resulting console output after the script is complete looks like this:

[[email protected] /home/brandon] > php test.php
Iteration 50 of 50 - Done
[[email protected] /home/brandon] >

Run the script for yourself to see what it looks like. Basically, the script counts from iteration 0 to 50, all on one line. It makes for very fancy console scripts 🙂

Leave a Reply