Issue
I currently have this bash script (which is located in my home directory, i.e., /home/username/
and I am running it as root as it's necessary for the icon copying lines):
cd /home/username/Pictures/Icon*
declare -a A={Arch,Debian,Fedora,Mageia,Manjaro,OpenSUSE}
declare -a B={Adwaita,Faenza,gnome,Humanity}
for i in $A; do
for j in $B; do
if test -e /usr/share/icons/$j/scalable ; else
mkdir /usr/share/icons/$j/scalable/
fi
if test -e /usr/share/icons/$j/scalable/$i.svg ; else
cp -a $i*.svg /usr/share/icons/$j/scalable/$i.svg
fi
done
done
What I want this script to do is to copy icons from my Pictures/Icons and logos
directory to the scalable
theme (specified in $B
) subdirectories in /usr/share/icons
. Before it does this, however, I'd like it to create a scalable
directory in these theme subdirectories if it does not already exist. The problem is that the else part of the conditionals is not being read properly, as I keep receiving this error:
./copyicon.sh: line 8: syntax error near unexpected token `else'
./copyicon.sh: line 8: ` if test -e /usr/share/icons/$j/scalable ; else'
If you're wondering why the test -e ...
in the conditional it's based on a textbook on bash scripting I've been following.
Solution
Checking file and/or directory existence
To check whether a file exists in bash, you use the -f
operator. For directories, use -d
. Example usage:
$ mkdir dir
$ [ -d dir ] && echo exists!
exists!
$ rmdir dir
$ [ -d dir ] && echo exists!
$ touch file
$ [ -f file ] || echo "doesn't exist..."
$ rm file
$ [ -f file ] || echo "doesn't exist..."
doesn't exist...
For more information simply execute man test
.
A note on -e
, this test operator checks whether a file exists. While this may seem like a good choice, it's better to use -f
which will return false if the file isn't a regular file. /dev/null
for example is a file but nor a regular file. Having the check return true is undesired in this case.
A note on variables
Be sure to quote variables too, once you have a space or any other special character contained in a variable it can have undesired side effects. So when you test for existence of files and directories, wrap the file/dir in double quotes. Something like [ -f "/path/to/some/${dir}/" ]
will work while the following would fail if there is a space in dir
: [ -f /path/to/some/${dir}/ ]
.
Fixing the syntax error
You are experiencing a syntax error in the control statements. A bash if
clause is structured as following:
if ...; then
...
fi
Or optional with an else
clause:
if ...; then
...
else
...
fi
You cannot omit the then
clause. If you wish to only use the else
clause you should negate the condition. Resulting in following code:
if [ ! -f "/usr/share/icons/$j/scalable" ]; then
mkdir "/usr/share/icons/$j/scalable/"
fi
Here we add an exclamation point (!
) to flip the expression's evaluation. If the expression evaluates to true, the same expression preceded by !
will return false and the other way around.
Answered By - ShellFish Answer Checked By - Candace Johnson (WPSolving Volunteer)