# Bash script that checks if font is installed and installs it if necessary

This checks if a font is installed by using fc-list and grep. If the particular font is not installed, it offers to install it for the user. This snippet is part of a larger script that installs a particular Conky configuration along with all of its dependencies with minimal effort from the user.

### Concerns

• I have to create the FONT_INSTALLED variable to avoid a "too many arguments" error by placing the code into the if statement, is there a better practice for handling this?
• To check if the font is installed, I check if the FONT_INSTALLED variable is a null String or not. Is this considered good practice? I know in languages such as Java a String is normally checked for length/content since the default value is "".
• I've seen that placing > /dev/null after a command that would normally have output hides the output. This seems slightly 'hacky' as I know commands such as wget have the -q or --quiet option to hide output. For commands that do not have such an option, what is the preferred method of hiding output?

I realize that I should not place semi-colons after each line as per the advice on my first question first question. I forgot to make the appropriate changes to this code snippet.

FONT_INSTALLED=$(fc-list | grep -i "roboto"); if [ -z "$FONT_INSTALLED" ]; then
echo "The Roboto font is not currently installed, would you like to install it now? (Y/N)";
if [[ "$response" == [yY] ]]; then echo "Installing the Roboto font to the ~/.fonts directory..."; mkdir .fonts/Roboto/ -p && wget --quiet -O ~/.fonts/Roboto/tmp.zip http://www.fontsquirrel.com/fonts/download/roboto && unzip ~/.fonts/Roboto/tmp.zip -d ~/.fonts/Roboto/ > /dev/null && rm ~/.fonts/Roboto/tmp.zip fc-cache -fv > /dev/null FONT_INSTALLED=$(fc-list | grep -i "roboto");
if [ -n "$FONT_INSTALLED" ]; then echo "The Roboto font was sucessfully installed!"; else echo "Something went wrong while trying to install the Roboto font."; fi else echo "Skipping the installation of the Roboto font..."; echo "Please note that this Conky configuration will not work without the Roboto font."; fi else echo "The Roboto font has already been installed."; fi  ## 3 Answers • I have to create the FONT_INSTALLED variable to avoid a "too many arguments" error by placing the code into the if statement, is there a better practice for handling this? You mean this part: FONT_INSTALLED=$(fc-list | grep -i "roboto");
if [ -z "$FONT_INSTALLED" ]; then  Instead of putting in a variable, you could put the $(...) itself into the if.

A better way would be to leverage the exit of grep in the if directly:

if fc-list | grep -i roboto >/dev/null; then


But since you use this check twice in your code, the best would be to put it in a function:

is_font_installed() {
fontname=$1 fc-list | grep -i "$fontname" >/dev/null
}


You could then use this in if statements like this:

if is_font_installed roboto; then

• To check if the font is installed, I check if the FONT_INSTALLED variable is a null String or not, is this considered good practice? I know in languages such as Java a String is normally checked for length/content since the default value is "".

My previous point answers that: use the exit code of a command when that's all you need.

Btw, there are no real null values in Bash. Null values are just empty strings.

• I've seen that placing > /dev/null after a command that would normally have output hides the output. This seems slightly 'hacky' as I know commands such as wget have the -q or --quiet option to hide output. For commands that do not have such an option, what is the preferred method of hiding output?

Placing > /dev/null means redirecting standard output to a black hole. It's a fine way to hide output, it's not 'hacky'. It's more verbose than using the -q flag, when such flag exists. But often > /dev/null is more portable than using the -q flag, as the flag might not be available in all implementations. For example grep -q works fine in any Linux, but won't work on some Solaris. So if you want to make your script as portable as possible, it's safest to use the longer > /dev/null instead.

If you are using then rather than mixing [ and [[, you should stick with one or the other, preferrably [[. See What is the difference between test, [ and [[ ?

You might also want to consider preferring printf over echo for a more robust approach. See this amazingly detailed analysis of why printf is better than echo.

• Nice, and it's especially informative with the links! May 1 '15 at 7:08

To check if the font is installed, I check the FONT_INSTALLED variable

Since you are using grep a more straightforward way is to test its exit status (\$?). It is 0 if some lines matched, and 1 if no line matched.

As a general recommendation, a font name shall be passed as an argument. Typing Roboto 12 times is not a good way to spend keystrokes. One day you may want to install another font.