How do I check whether a file or file directory exist in bash?

守給你的承諾、 提交于 2021-02-04 12:23:21

问题


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.


回答1:


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.




回答2:


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.



来源:https://stackoverflow.com/questions/30992072/how-do-i-check-whether-a-file-or-file-directory-exist-in-bash

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!