Как проверить, существует ли файл или каталог в bash
Часто при написании сценариев оболочки вы можете оказаться в ситуации, когда вам нужно выполнить действие в зависимости от того, существует файл или нет.
В Bash вы можете использовать команду test, чтобы проверить, существует ли файл, и определить тип файла.
Команда test принимает одну из следующих синтаксических форм:
test EXPRESSION
[ EXPRESSION ]
[[ EXPRESSION ]]
Если вы хотите, чтобы ваш сценарий был переносимым, вам следует предпочесть старую команду test [
, которая доступна во всех оболочках POSIX. Новая обновленная версия тестовой команды [[
(двойные скобки) поддерживается в большинстве современных систем, использующих Bash, Zsh и Ksh в качестве оболочки по умолчанию.
Проверьте, существует ли файл
При проверке существования файла наиболее часто используются операторы FILE -e
и -f
. Первый проверит, существует ли файл независимо от типа, а второй вернет истину, только если ФАЙЛ является обычным файлом (а не каталогом или устройством).
Наиболее удобочитаемый вариант при проверке существования файла — использование команды test
в сочетании с оператором if
. Любой из приведенных ниже фрагментов проверит, существует ли файл /etc/resolv.conf
:
FILE=/etc/resolv.conf
if test -f "$FILE"; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
fi
FILE=/etc/resolv.conf
if [[ -f "$FILE" ]]; then
echo "$FILE exists."
fi
Если вы хотите выполнить другое действие в зависимости от того, существует файл или нет, просто используйте конструкцию if / then:
FILE=/etc/resolv.conf
if [ -f "$FILE" ]; then
echo "$FILE exists."
else
echo "$FILE does not exist."
fi
Всегда используйте двойные кавычки, чтобы избежать проблем при работе с файлами, в именах которых есть пробелы.
Вы также можете использовать команду test без оператора if. Команда после оператора &&
будет выполнена только в том случае, если статус выхода тестовой команды — истина,
test -f /etc/resolv.conf && echo "$FILE exists."
[ -f /etc/resolv.conf ] && echo "$FILE exists."
[[ -f /etc/resolv.conf ]] && echo "$FILE exists."
Если вы хотите запустить серию команд после оператора &&
просто заключите команды в фигурные скобки, разделенные ;
или &&
:
[ -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
(или &&
с [[
), чтобы проверить, существует ли несколько файлов:
if [ -f /etc/resolv.conf -a -f /etc/hosts ]; then
echo "Both files exist."
fi
if [[ -f /etc/resolv.conf && -f /etc/hosts ]]; then
echo "Both files exist."
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
— Истина, если ФАЙЛ существует и является исполняемым.
Только полноправные пользователи могут оставлять комментарии. Аутентифицируйтесь пожалуйста, используя сервисы.