How to check if a file or file directory exists in bash?

I currently have this bash script (which is in my home directory, i.e. /home/fusion809/ , and I run it as root, as needed for the icon copy strings):

 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 

I want this script to copy the icons from my Pictures/Icons and logos directory into the scalable tags (specified in $B ) of the subdirectories in /usr/share/icons . However, before doing this, I would like to create a scalable directory in these theme subdirectories, if it does not already exist. The problem is that the other part of the conditional expressions is not being read properly, as I keep getting 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 test -e ... in the conditional case, it is based on a tutorial on bash scripts that I am following.

+6
source share
2 answers

Checking the existence of a file and / or directory

To check if a file exists in , you use the -f operator. For directories, use -d . Usage example:

 $ 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, just run man test .

Note in -e , this test statement checks if a file exists. Although this might seem like a good choice, it's best to use -f , which will return false if the file is not a regular file. /dev/null for example, this is a file, but not a regular file. In this case, an error returning true in this case is undesirable.

Variable Note

Do not forget to specify the variables, if you have a space or any other special character contained in the variable, it may have undesirable side effects. Therefore, when you check for files and directories, wrap the / dir file in double quotes. Something like [ -f "/path/to/some/${dir}/" ] will work until the following is done if there is a space in dir : [ -f /path/to/some/${dir}/ ] .

Fix syntax error

You have a syntax error in control statements. The bash if clause is structured as follows:

 if ...; then ... fi 

Or optionally with an else clause:

 if ...; then ... else ... fi 

You cannot omit the then clause. If you want to use only the else clause, you must cancel this condition. The result of the following code:

 if [ ! -f "/usr/share/icons/$j/scalable" ]; then mkdir "/usr/share/icons/$j/scalable/" fi 

Here we add an exclamation mark ( ! ) To reverse the evaluation of the expression. If the expression is true, then the same expression is preceded by ! will return false and vice versa.

+6
source

You cannot skip the next part of the if statement, the simplest solution would be to simply cancel 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 the material (e.g. / usr / share / icons / $ j / scalable / exists, but this is a file, not a directory for any reason.) I also noticed that in your source 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 this way in my example, if you are sure that it is always only one file and intentionally renames it. If not, I would suggest just specifying the destination directory.

+3
source

Source: https://habr.com/ru/post/989563/


All Articles