Fireworks from the Command Line
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;
| Attachment | Size |
|---|---|
| happy4j.sh_.txt | 2.89 KB |
Mitch Frazier is an Associate Editor for Linux Journal.
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- RSS Feeds
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Dynamic DNS—an Object Lesson in Problem Solving
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- Tech Tip: Really Simple HTTP Server with Python
- myip
24 min 58 sec ago - Keeping track of IP address
2 hours 15 min ago - Roll your own dynamic dns
7 hours 29 min ago - Please correct the URL for Salt Stack's web site
10 hours 40 min ago - Android is Linux -- why no better inter-operation
12 hours 56 min ago - Connecting Android device to desktop Linux via USB
13 hours 24 min ago - Find new cell phone and tablet pc
14 hours 22 min ago - Epistle
15 hours 51 min ago - Automatically updating Guest Additions
17 hours 11 sec ago - I like your topic on android
17 hours 46 min ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?



Comments
Thanks
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
Syntax error?
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
Not Bash
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.
Thanks! Left my bash prompt
Thanks!
Left my bash prompt a red colour after the show - or maybe that's just my eyes having been dazzled ;)
Reset Color on Exit
Add the following line to the end of the script.
That should reset the color.
Mitch Frazier is an Associate Editor for Linux Journal.
Retro ASCII Goodness
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!