Fireworks from the Command Line

July 2nd, 2009 by Mitch Frazier in

Your rating: None Average: 4.7 (7 votes)

To kick off the upcoming 4th of July celebrations we present the following bash script for your enjoyment.

If you'd rather not try to figure out what it does, watch the video.

Have a safe and Happy 4th of July!

#!/bin/bash

rows=$(tput lines)
cols=$(tput cols)
colors=(red green blue purple cyan yellow brown)
lock_file=
lock_file_base=/tmp/$(basename $0 .sh)

multiple=0
if [[ "$1" ]]; then
    nsingle=$1
    shift
else
    nsingle=10
fi
if [[ "$1" ]]; then
    nmultiple=$1
    shift
    if [[ $nmultiple -gt 8 ]]; then nmultiple=8; fi
else
    nmultiple=6
fi


function colorstr()
{
    local  row=$1
    local  col=$2
    local  color=$3
    local  v
    case "$color" in
    red)     v=31;;
    green)   v=34;;
    blue)    v=32;;
    purple)  v=35;;
    cyan)    v=36;;
    yellow)  v=33;;
    brown)   v=33;;
    white)   v=37;;
    *)       v=;;
    esac
    shift 3

    if [[ $multiple -ne 0 ]]; then
        touch $lock_file
        while [[ $(ls $lock_file_base.* 2>/dev/null | head -n 1) != $lock_file ]]
        do
            sleep 0.05
        done
    fi
        
    tput cup $row $col
    echo -n -e "\e["$v"m"
    set -f
    echo -n $*
    set +f
    if [[ $multiple -ne 0 ]]; then
        rm -f $lock_file
    fi
}

function center_colorstr()
{
    local  row=$1
    local  color=$2
    shift 2
    local  s="$*"
    local  slen=${#s}
    colorstr $row $(((cols / 2) - (slen / 2))) $color "$s"
}

function fireworks()
{
    local row=$((rows - 1))
    local col=$(((RANDOM % (cols / 2)) + (cols / 4)))
    local height=$((RANDOM % rows - 2))
    local slant
    local h
    local color1=${colors[$((RANDOM % ${#colors[*]}))]}
    local color2=${colors[$((RANDOM % ${#colors[*]}))]}
    local color3=${colors[$((RANDOM % ${#colors[*]}))]}
    while [[ $color1 == $color2  ||  $color1 == $color3  ||  $color2 == $color3 ]]
    do
        color2=${colors[$((RANDOM % ${#colors[*]}))]}
        color3=${colors[$((RANDOM % ${#colors[*]}))]}
    done

    case $((RANDOM % 4)) in
    0) slant=-2;;
    1) slant=-1;;
    2) slant=1;;
    3) slant=2;;
    esac

    if [[ $height -gt 5 ]]; then
        h=$height

        while [[ $h -gt 0 ]]
        do
            colorstr $row $col $color1 '.'
            let row--
            if [[ $((col + slant)) -ge $((cols - 3))  ||  $((col + slant)) -le 2 ]]; then break; fi
            let col+=slant
            let h--
            sleep 0.1
        done

        if [[ $((col + slant)) -lt $((cols - 3))  &&  $((col + slant)) -gt 2 ]]; then

            h=$((height / 5))

            while [[ $h -gt 0 ]]
            do
                colorstr $row $col $color2 '.'
                let row++
                if [[ $((col + slant)) -ge $((cols - 3))  ||  $((col + slant)) -le 2 ]]; then break; fi
                let col+=slant
                let h--
                sleep 0.1
            done
        fi

        colorstr $((row)) $((col - 1)) $color3 '***'
        colorstr $((row - 1)) $((col)) $color3 '*'
        colorstr $((row + 1)) $((col)) $color3 '*'
    fi
}

for i in $(seq 1 $nsingle)
do
    clear
    fireworks
    sleep 1
done

clear

pids=
for i in $(seq 1 $nmultiple)
do
    let multiple++
    lock_file=$lock_file_base.$i
    fireworks &
    pids="$pids $!"
done

trap "kill -9 $pids 2>/dev/null" EXIT

wait $pids
sleep 3

clear
center_colorstr $((rows / 2 - 1)) red "Hope you enjoyed the show!"
center_colorstr $((rows / 2 + 1)) red "Happy 4th of July"
center_colorstr $((rows / 2 + 3)) red "Your Friends at Linux Journal"
echo

sleep 5
clear


# vim: tabstop=4: shiftwidth=4: noexpandtab:
# kate: tab-width 4; indent-width 4; replace-tabs false;
__________________________

Mitch Frazier is an Associate Editor for Linux Journal and the Web Editor for linuxjournal.com.

AttachmentSize
happy4j.sh_.txt2.89 KB


Special Magazine Offer -- Free Gift with Subscription
Receive a free digital copy of Linux Journal's System Administration Special Edition as well as instant online access to current and past issues. CLICK HERE for offer

Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
JimmyK's picture

Thanks

On July 5th, 2009 JimmyK (not verified) says:

Thanks! A tip o' the hat to ye </:-0 . This inspired me to get back to learning bashscripts at bashscripts.org. I've been neglecting my mind and forgot how to even run a script :-( JimmyK

Technoslick's picture

Syntax error?

On July 3rd, 2009 Technoslick (not verified) says:

Copied/pasted script text to new file as well as tired saving/renaming article link for script text to new file. When run:

happy4j.sh: 5: Syntax error: "(" unexpected

???

Ubuntu 9.04 Jaunty

Mitch Frazier's picture

Not Bash

On July 3rd, 2009 Mitch Frazier says:

At some point Ubuntu stopped making bash the default shell and changed to dash, so if you run the script via "sh happy4j.sh" you end up running it with dash rather than bash. Run it via "bash happy4j.sh" or make it executable with "chmod +x happy4j.sh" and then run it directly via "./happy4j.sh".

I'm not an Ubuntu user so I tend to assume that sh == bash... I probably should stop doing that.

So you may be wondering "what's the value of the shebang (#!) at the top of a script if it doesn't work with all shells?" Well, the answer is that the shebang is not understood by shells: it's understood by the O/S itself. That's why making the script executable and running it directly works.

When the O/S (Linux) opens an executable file (something that has the x bit set) it reads the first two bytes and checks to see if they are equal to "#!". If they are equal, the O/S then executes the program specified in the remainder of the first line rather than the original file and passes the original file name to it as an argument.

__________________________

Mitch Frazier is an Associate Editor for Linux Journal and the Web Editor for linuxjournal.com.

Jon Brett's picture

Thanks! Left my bash prompt

On July 3rd, 2009 Jon Brett (not verified) says:

Thanks!

Left my bash prompt a red colour after the show - or maybe that's just my eyes having been dazzled ;)

Mitch Frazier's picture

Reset Color on Exit

On July 3rd, 2009 Mitch Frazier says:

Add the following line to the end of the script.

echo -n -e "\e[m"

That should reset the color.

__________________________

Mitch Frazier is an Associate Editor for Linux Journal and the Web Editor for linuxjournal.com.

Tony Miller's picture

Retro ASCII Goodness

On July 2nd, 2009 Tony Miller (not verified) says:

Ahhh, this brings back memories of getting the latest computer mag in the 80s, typing in the listing, and hoping for the best. Now, though, I can copy and paste from a web browser into vim, save, chmod, and sit back and enjoy the show.

Very nice old skool display. Thanks!

Post new comment

Please note that comments may not appear immediately, so there is no need to repost your comment.
The content of this field is kept private and will not be shown publicly.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <pre> <ul> <ol> <li> <dl> <dt> <dd> <i> <b>
  • Lines and paragraphs break automatically.

More information about formatting options

Newsletter

Each week Linux Journal editors will tell you what's hot in the world of Linux. You will receive late breaking news, technical tips and tricks, and links to in-depth stories featured on www.linuxjournal.com.
Sign up for our Email Newsletter

Tech Tip Videos

From the Magazine

December 2009, #188

If last month's Infrastrucuture issue was too "big" for you then try on this month's Embedded issue. Find out how to use Player for programming mobile robots, build a humidity controller for your root cellar, find out how to reduce the boot time of your embedded system, and if you're new to embedded systems find out the basics that go into one. You can also read about the Beagle Board, the Mesh Potato and a spate of other interestingly named items. And along with our regular columns don't miss our new monthly column: Economy Size Geek.







Read this issue