Bash: как проверить, существует ли файл или папка

Категория: Bash · Язык: Bash · Обновлено:

Чтобы проверить, существует ли файл, в Bash используют условие [ -f путь ]. Для папки [ -d путь ], для любого объекта файловой системы [ -e путь ]. Внутри скобок обязательны пробелы, а путь лучше брать в двойные кавычки.

Основные проверки

Условие

Истинно, если

-e путь

Путь существует (файл, папка, ссылка)

-f путь

Это обычный файл

-d путь

Это папка

-s путь

Файл существует и не пустой

-L путь

Это символическая ссылка

-r путь, -w путь, -x путь

Есть право на чтение, запись, выполнение

-z "$строка"

Строка пустая

-n "$строка"

Строка не пустая

Условие if

Bash
file="/tmp/check/config.ini"

if [ -f "$file" ]; then
  echo "Файл есть"
else
  echo "Файла нет"
fi

В одну строку

Bash
[ -f "$file" ] && echo "есть" || echo "нет"
[ -d /tmp/check ] && echo "папка есть"

Отрицание: файла нет

Bash
if [ ! -f "$file" ]; then
  echo "Файл не найден: $file" >&2
  exit 1
fi

Сообщения об ошибках принято отправлять в поток ошибок: >&2.

Создать, если нет

Bash
[ -d /tmp/check/logs ] || mkdir -p /tmp/check/logs     # или просто mkdir -p, он не ругается на существующую папку
[ -f "$file" ] || touch "$file"

Файл есть, но пустой

Bash
if [ -s "$file" ]; then
  echo "Файл не пустой"
else
  echo "Файл пустой или отсутствует"
fi

Двойные скобки и несколько условий

Bash
if [[ -f "$file" && -r "$file" ]]; then
  echo "Файл существует и доступен для чтения"
fi

Двойные скобки [[ ]] есть в Bash, но отсутствуют в строгом POSIX sh. Внутри них кавычки вокруг переменных не обязательны, но привычка ставить их безопасна.

Проверить маску файлов

Условие -f не понимает шаблоны вроде *.log. Для масок подойдёт ls или compgen:

Bash
if compgen -G "/tmp/check/*.log" > /dev/null; then
  echo "Логи найдены"
fi

Частые вопросы

Почему выдаёт «too many arguments» или «unary operator expected»?

Путь содержит пробел или переменная пустая, а кавычек нет. Всегда пишите [ -f "$file" ].

Чем -e отличается от -f?

-e истинно для любого существующего пути, включая папки. -f только для обычных файлов.

Как проверить существование команды, а не файла?

Используйте command -v имя: command -v git >/dev/null || echo "git не установлен".