I currently have this bash script (which is located in my home directory, i.e., /home/fusion809/
and I am running it as root as it's necessary for the icon copying lines):
cd /home/fusion809/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.
The -e flag is to check whether the files or the directories exist or not. The -f flag is to check whether the ordinary files (not directories) exist or not. Finally, the -d flag is to check whether this is a directory or not.
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}/ ]
.
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.
You can't skip the then part of the if statement, easiest solution would be to just negate the test
if [[ ! -e /usr/share/icons/${j}/scalable ]] ; then
mkdir /usr/share/icons/${j}/scalable/
fi
if [[ ! -e /usr/share/icons/${j}/scalable/${i}.svg ]] ; then
cp -a ${i}*.svg /usr/share/icons/${j}/scalable/${i}.svg
fi
I left it with -e (exists), but you might consider using -d for directories or -f for files and some error handling to catch stuff (e.g. /usr/share/icons/$j/scalable/ exists, but is a file and not a directory for whatever reason.) I also noticed that in your original code you are potentially trying to copy multiple files into one:
cp -a $i*.svg /usr/share/icons/$j/scalable/$i.svg
I left it that way in my example in case you are sure that it is always only one file and are intentionally renaming it. If not I'd suggest only specifying a target directory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With