Введение
Много раз при написании сценариев оболочки вы можете оказаться в ситуации, когда вам нужно выполнить действие в зависимости от того, существует файл или нет.
В Bash вы можете использовать команду test для проверки существования файла и определения типа файла.
Команда test использует одну из следующих форм синтаксиса:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
Если вы хотите, чтобы ваш сценарий был переносимым, вам лучше использовать старую команду [
test, которая доступна во всех оболочках POSIX. Новая обновленная версия команды test [[
(двойные скобки) поддерживается в большинстве современных систем, использующих Bash, Zsh и Ksh в качестве оболочки по умолчанию.
Проверьте, существует ли файл
При проверке существования файла чаще всего используются операторы FILE -e
и -f
. Первый будет проверять, существует ли файл независимо от его типа, а второй вернет true только в том случае, если ФАЙЛ является обычным файлом (не каталогом или устройством).
Самый читаемый вариант проверки существования файла — использование команды test в сочетании с оператором if. Приведенные ниже сценарии проверят, существует ли файл /etc/resolv.conf
:
FILE=/etc/resolv.conf
if test -f "$FILE"; then
echo "$FILE exist"
fi
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exist"
fi
FILE=/etc/resolv.conf
if [[ -f "$FILE" ]]; then
echo "$FILE exist"
fi
Если вы хотите выполнить другое действие в зависимости от того, существует файл или нет, просто используйте конструкцию if /then:
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exist"
else
echo "$FILE does not exist"
fi
Всегда используйте двойные кавычки, чтобы избежать проблем при работе с файлами, содержащими пробелы в именах.
Вы также можете использовать команду test без оператора if. Команда после оператора &&
будет выполняться только в том случае, если статус выхода тестовой команды равен true,
test -f /etc/resolv.conf && echo "$FILE exist"
[ -f /etc/resolv.conf ] && echo "$FILE exist"
[[ -f /etc/resolv.conf ]] && echo "$FILE exist"
Если вы хотите выполнить серию команд после оператора &&
, просто заключите команды в фигурные скобки, разделенные ;
о &&
:
[ -f /etc/resolv.conf ] && { echo "$FILE exist"; cp "$FILE" /tmp/; }
После &&
оператор, следующий за оператором ||
она будет выполнена только в том случае, если статус выхода тестовой команды равен false
.
[ -f /etc/resolv.conf ] && echo "$FILE exist" || echo "$FILE does not exist"
Проверить, существует ли каталог
Операторы -d
позволяют проверить, является ли файл каталогом или нет.
Например, чтобы проверить, существует ли каталог /etc/docker
, вы должны использовать:
FILE=/etc/docker
if [ -d "$FILE" ]; then
echo "$FILE is a directory"
fi
[ -d /etc/docker ] && echo "$FILE is a directory"
Вы также можете использовать двойные скобки [[
вместо одинарной [
.
Проверьте, не существует ли файл
Как и во многих других языках, тестовое выражение можно инвертировать с помощью нелогического оператора !
(Восклицательный знак):
FILE=/etc/docker
if [! -f "$FILE" ]; then
echo "$FILE does not exist"
fi
Как указано выше:
[! -f /etc/docker ] && echo "$FILE does not exist"
Проверьте, есть ли несколько файлов
Вместо использования вложенных конструкций if/else вы можете использовать -a
(или &&
с [[
) для проверки существования нескольких файлов:
FILE=/etc/docker
if [ -f /etc/resolv.conf -a -f /etc/hosts ]; then
echo "$FILE is a directory"
fi
FILE=/etc/docker
if [ -f /etc/resolv.conf && -f /etc/hosts ]; then
echo "$FILE is a directory"
fi
Эквивалентные варианты без использования оператора IF:
[ -f /etc/resolv.conf -a -f /etc/hosts ] && echo "both files exist"
[[ -f /etc/resolv.conf && -f /etc/hosts ]] && echo "both files exist"
Операторы тестовых команд
Команда test включает следующие операторы FILE, позволяющие тестировать определенные типы файлов:
-b FILE
— Истинно, если ФАЙЛ существует и является блочным специальным файлом.-c FILE
— Истинно, если ФАЙЛ существует и является файлом со специальными символами.-d FILE
— Истинно, если ФАЙЛ существует и является каталогом.-e FILE
— Истинно, если ФАЙЛ существует и является файлом, независимо от типа (узел, каталог, сокет и т. д.).-f FILE
— Истинно, если ФАЙЛ существует и является обычным файлом (не каталогом или устройством).-G FILE
— Истинно, если ФАЙЛ существует и принадлежит к той же группе, что и пользователь, выполняющий команду.-h FILE
— Истинно, если ФАЙЛ существует и является символической ссылкой.-g FILE
— Истинно, если ФАЙЛ существует и для него установлен флаг set-group-id (sgid).-k FILE
— Истинно, если ФАЙЛ существует и для него установлен битовый флаг закрепления.-L FILE
— Истинно, если ФАЙЛ существует и является символической ссылкой.-O FILE
— Истинно, если ФАЙЛ существует и принадлежит пользователю, выполняющему команду.-p FILE
— Истинно, если ФАЙЛ существует и является каналом.-r FILE
— Истинно, если ФАЙЛ существует и доступен для чтения.-S FILE
— Истинно, если ФАЙЛ существует и является сокетом.-s FILE
— Истинно, если ФАЙЛ существует и имеет ненулевой размер.-u FILE
— Истинно, если флаг существует и установлен set-user-id (suid).-w FILE
— Истинно, если ФАЙЛ существует и доступен для записи.-x FILE
— Истинно, если ФАЙЛ существует и является исполняемым.
Вывод
В этом руководстве мы показали вам, как проверить, существует ли файл или каталог с помощью Bash.