Improved and commented code:
#!/bin/bash
num=${1:-undefined} # If $1 (the first argument passed to the script) is set, then num=$1, else num=undefined.
cmd=$(which {banner,echo} | head -1 | xargs basename) # If banner is installed, then cmd=baner, else cmd=echo.
until [[ "$num" =~ ^[0-9]+$ ]]; do # Until $num become a valid number (loop will not be executed if $1 is set):
read -p "Type a number: " num # Ask the user for a valid number.
done # End of the until loop.
for ((num;num>=0;num--)); do # Loop using $num as variable; while $num is greater or equal than zero; num=$num-1.
$cmd $num # Runs $cmd (banner or echo) passing $num as argument.
sleep 1 # Stop the program execution for one second.
done # End of the for loop.
The above code will include zero in the countdown, if do you want to stop when the countdown reaches 1, then you only need to make a few changes:
In the 6th line, change ^[0-9]+$
by ^[1-9]+[0-9]*$
so it looks like this:
until [[ "$num" =~ ^[1-9]+[0-9]*$ ]]; do # Until $num become a valid number (loop will not be executed if $1 is set):
In the 10th line, remove the =
sign so it looks like this (I've updated also the comment):
for ((num;num>0;num--)); do # Loop using $num as variable; while $num is strictly greater than zero; num=$num-1.
Your original program doesn't work because:
- You not passed a number as argument to the program.
- A example invocation of this command is
./countdown 5
where 5
is the number.
If do you want to handle this, you can add a else
to your code (look a the five last lines):
#!/bin/bash
#countdown
#counts down to 0 from whatever number you give it
#displaying a number each second
NUM=${1:-0}
if [ $NUM -gt 0 ]
then
while [ $NUM -gt 0 ]
do
if [ -f /usr/bin/banner ]
then
/usr/bin/banner "$NUM"
else
echo $NUM
fi
NUM=$(($NUM-1))
sleep 2
done
else
echo "Error: number not specified."
echo "Usage: $0 <number>"
exit 1
fi
NUM=${1:-0}
means:
${PARAMETER:-WORD}
If the parameter PARAMETER
is unset (never was defined) or null
(empty), this one expands to WORD
, otherwise it expands to the value
of PARAMETER
, as if it just was ${PARAMETER}
.
echo "Your home directory is: ${HOME:-/home/$USER}."
echo "${HOME:-/home/$USER} will be used to store your personal data."
If HOME
is unset or empty, everytime you want to print something
useful, you need to put that parameter syntax in.
Source: http://wiki.bash-hackers.org/syntax/pe#use_a_default_value
In your case, it means that, if you passed a argument to the script, NUM
will be equal to that argument, else, NUM
will be equal to 0
NUM=${1:-0}
? – Ken Sharp Apr 13 '15 at 15:28./countdown 30
. – Jos Apr 13 '15 at 15:52