Как проверить, существует ли файл или каталог файлов в bash?
в настоящее время у меня есть этот скрипт bash (который находится в моем домашнем каталоге, т. е. /home/fusion809/
и я запускаю его как root, поскольку это необходимо для строк копирования значков):
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
что я хочу, чтобы этот скрипт сделал, это скопировать значки из моего до scalable
тема (указанному в $B
) поддиректориях в /usr/share/icons
. Однако, прежде чем он это сделает, я хотел бы создать scalable
каталог в этих подкаталогах темы, если он еще не существует. Проблема это то, что другая часть conditionals не читается должным образом, так как я продолжаю получать эту ошибку:
./copyicon.sh: line 8: syntax error near unexpected token `else'
./copyicon.sh: line 8: ` if test -e /usr/share/icons/$j/scalable ; else'
Если вам интересно, почему test -e ...
в условном он основан на учебнике по сценариям bash, за которым я следил.
2 ответов
проверка существования файла и/или каталога
чтобы проверить, существует ли файл в Баш, вы используете -f
оператора. Для каталогов, используйте -d
. Пример использования:
$ 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...
для получения дополнительной информации просто выполнить man test
.
Примечание -e
этот оператор проверяет, существует ли файл. Хотя это может показаться хорошим выбором, лучше использовать -f
который вернет false, если файл не является обычным файлом. /dev/null
например, это файл, но не обычный файл. В этом случае возврат проверки true нежелателен.
примечание по переменным
не забудьте также процитировать переменные, как только у вас есть пробел или любой другой специальный символ, содержащийся в переменной, он может иметь нежелательные побочные эффекты. Поэтому, когда вы проверяете наличие файлов и каталогов, оберните файл/dir в двойные кавычки. Что-то вроде [ -f "/path/to/some/${dir}/" ]
будет работать, пока следующее не удастся, если есть место в dir
: [ -f /path/to/some/${dir}/ ]
.
исправление синтаксической ошибки
в операторах управления возникает синтаксическая ошибка. Баш if
предложение структурировано следующим образом:
if ...; then
...
fi
или необязательно с else
статья:
if ...; then
...
else
...
fi
вы не можете пропустить then
предложения. Если вы хотите использовать только else
предложение вы должны отрицать условие. В результате получается следующий код:
if [ ! -f "/usr/share/icons/$j/scalable" ]; then
mkdir "/usr/share/icons/$j/scalable/"
fi
здесь мы добавить восклицательный знак (!
), чтобы перевернуть оценку выражения. Если выражение имеет значение true, то этому же выражению предшествует !
вернет false и наоборот.
вы не можете пропустить затем часть Если заявление, самым простым решением было бы просто отрицать тест
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
Я оставил его с-e (существует), но вы можете использовать-d для каталогов или-f для файлов и некоторой обработки ошибок, чтобы поймать материал (например, / usr / share / icons / $j / масштабируемый/ существует, но является файлом, а не каталогом по какой-либо причине.) Я также заметил, что в исходном коде вы потенциально пытаетесь скопировать несколько файлов в один:
cp -a $i*.svg /usr/share/icons/$j/scalable/$i.svg
Я оставил его в моем примере в случае, если вы уверены, что это всегда только один файл и намеренно переименовав его. Если нет, я бы предложил только указать целевой каталог.