Как проверить, существует ли файл в сценариях Linux Bash
Опубликовано: 2022-08-18Если сценарий Linux Bash зависит от наличия определенных файлов или каталогов, он не может просто предположить, что они существуют. Нужно проверить, что они точно есть. Вот как это сделать.
Ничего не предполагай
Когда вы пишете сценарий, вы не можете делать предположения о том, что есть на компьютере, а что нет. Это вдвойне верно, если сценарий будет распространяться и работать на многих разных компьютерах. Рано или поздно скрипт запустится на компьютере, который не соответствует вашим предположениям, и скрипт выйдет из строя или заработает непредсказуемо.
Все, что мы ценим или создаем на компьютере, хранится в файле определенного формата, и все эти файлы находятся в каталоге. Скрипты могут читать, записывать, переименовывать, удалять и перемещать файлы и каталоги — все то, что вы можете делать в командной строке.
Преимущество, которое у вас есть как у человека, заключается в том, что вы можете видеть содержимое каталога и знать, существует ли файл или нет, или существует ли вообще ожидаемый каталог. Если скрипт дает сбой при манипулировании файлами, это может привести к серьезным и разрушительным последствиям.
Bash предоставляет полный набор тестов, которые можно использовать для обнаружения файлов и каталогов и проверки многих их атрибутов. Включить их в скрипты несложно, но преимущества с точки зрения надежности и точного контроля значительны.
СВЯЗАННЫЕ С: Как использовать условные тесты с двойными скобками в Linux
Диапазон тестов
Комбинируя оператор if с соответствующим тестом из большой коллекции тестов файлов и каталогов, мы можем легко определить, существует ли файл, является ли он исполняемым или доступным для записи, и многое другое.
- -b : возвращает true, если файл является блочным специальным файлом.
- -c : возвращает true, если файл является специальным символом.
- -d : возвращает true, если «файл» является каталогом.
- -e : возвращает true, если файл существует.
- -f : возвращает true, если файл существует и является обычным файлом.
- -g : возвращает true, если файл имеет набор разрешений
setgid
(chmod g+
). - -h : возвращает true, если файл является символической ссылкой.
- -L : возвращает true, если файл является символической ссылкой.
- -k : возвращает true, если установлен липкий бит (
chmod +t
). - -p : возвращает true, если файл является именованным каналом.
- -r : возвращает true, если файл доступен для чтения.
- -s : возвращает true, если файлы существуют и не пусты.
- -S : возвращает true, если файл является сокетом.
- -t : возвращает true, если дескриптор файла открыт в терминале.
- -u : возвращает true, если файл имеет набор разрешений
setuid
(chmod u+
). - -w : возвращает true, если файл доступен для записи.
- -x : возвращает true, если файл является исполняемым.
- -O : возвращает true, если принадлежит вам.
- -G : возвращает true, если принадлежит вашей группе.
- -N : возвращает true, если файл был изменен с момента последнего чтения.
- ! : Логический оператор НЕ.
- && : Логический оператор И.
- || : Логический оператор ИЛИ.
Список начинается с -b
, потому что тест -a
устарел и заменен тестом -e
.
СВЯЗАННЫЕ С: Как использовать SUID, SGID и Sticky Bits в Linux
Использование тестов в сценариях
Универсальный оператор file test if
представляет собой простую конструкцию сценария. Сравнение внутри двойных скобок « [[ ]]
» использует проверку -f
, чтобы определить, существует ли обычный файл с таким именем.
Скопируйте текст этого скрипта в редактор и сохраните его в файл с именем «script1.sh» и используйте chmod
, чтобы сделать его исполняемым.
#!/бин/баш если [[ -f $1 ]] тогда echo "Файл $1 существует." еще echo "Файл $1 не найден." фи
Вы должны передать имя файла сценарию в командной строке.
chmod +x script1.sh
Вам нужно будет сделать это с каждым скриптом, если вы хотите попробовать другие примеры из статьи.
Давайте попробуем скрипт на простом текстовом файле.
./script1.sh тестовый файл.txt
Файл существует, и скрипт правильно сообщает об этом факте. Если мы удалим файл и попробуем снова, тест должен завершиться неудачно, и скрипт должен сообщить нам об этом.
./script1.sh тестовый файл.txt
В реальной ситуации ваш сценарий должен был бы предпринять любое подходящее действие. Возможно, он помечает ошибку и останавливается. Может быть, он создает файл и продолжает. Он может скопировать что-то из резервного каталога, чтобы заменить отсутствующий файл. Все зависит от цели скрипта. Но, по крайней мере, теперь скрипт может принимать решение, зная, присутствует файл или нет.
Флаг -f
проверяет наличие файла и является ли он «обычным» файлом. Другими словами, это не то, что кажется файлом, но таковым не является, например, файл устройства.
Мы воспользуемся ls для проверки существования файла «/dev/random», а затем посмотрим, что с ним сделает скрипт.
ls -lh /dev/случайный
./скрипт /dev/случайный
Поскольку наш скрипт тестирует обычные файлы, а «/dev/random» — это файл устройства, тест завершается неудачно. Очень часто, чтобы понять, существует ли файл, вам нужно тщательно выбрать, какой тест вы используете, или вам нужно использовать несколько тестов.
Это «script2.sh», который проверяет обычные файлы и файлы символьных устройств.
#!/бин/баш если [[ -f $1 ]] тогда echo "Файл $1 существует." еще echo "Файл $1 отсутствует или не является обычным файлом." фи если [[ -c $1 ]] тогда echo "Файл $1 является файлом символьного устройства." еще echo "Файл $1 отсутствует или не является специальным файлом." фи
Если мы запустим этот скрипт в файле устройства «/dev/random», первый тест, как мы и ожидали, завершится неудачно, а второй завершится успешно. Он распознает файл как файл устройства.
./script2.sh /dev/случайный
На самом деле, он распознает его как файл символьного устройства. Некоторые файлы устройств являются файлами блочных устройств. В нынешнем виде наш скрипт с ними не справится.
./script2.sh /dev/sda
Мы можем использовать логический оператор OR
и включить еще один тест во второй оператор if. На этот раз, независимо от того, является ли файл файлом символьного устройства или файлом блочного устройства, тест вернет значение true. Это «script3.sh».
#!/бин/баш если [[ -f $1 ]] тогда echo "Файл $1 существует." еще echo "Файл $1 отсутствует или не является обычным файлом." фи если [[ -c $1 || -b $1 ]] тогда echo "Файл $1 является файлом символьного или блочного устройства." еще echo "Файл $1 отсутствует или не является специальным файлом." фи
Этот сценарий распознает файлы как символьных, так и блочных устройств.
./script3.sh /dev/случайный
./script3.sh /dev/sda
Если вам важно различать разные типы файлов устройств, вы можете использовать вложенные операторы if
. Это «script4.sh».
#!/бин/баш если [[ -f $1 ]] тогда echo "Файл $1 существует." еще echo "Файл $1 отсутствует или не является обычным файлом." фи если [[ -c $1 ]] тогда echo "Файл $1 является файлом символьного устройства." еще если [[ -b $1 ]] тогда echo "Файл $1 является файлом блочного устройства." еще echo "Файл $1 отсутствует или не является файлом устройства." фи фи
Этот сценарий распознает и классифицирует файлы как символьных, так и блочных устройств.
./script4.sh /dev/случайный
./script4.sh /dev/sda
С помощью логического оператора И мы можем проверить сразу несколько характеристик. Это «script5.sh». Он проверяет, существует ли файл и есть ли у скрипта права на чтение и запись для него.
#!/бин/баш если [[ -f $1 && -r $1 && -w $1 ]] тогда echo "Файл $1 существует, и у нас есть права на чтение/запись." еще echo "Файл $1 отсутствует, это не обычный файл, или мы не можем его прочитать/записать." фи
Мы запустим скрипт на файле, который принадлежит нам и тому, который принадлежит пользователю root
.
./script5.sh .bashrc
./script5.sh /etc/fstab
Чтобы проверить существование каталога, используйте тест -d
. Это «script6.sh». Это часть сценария резервного копирования. Первое, что он делает, это проверяет, существует ли каталог, переданный в командной строке, или нет. Он использует логический оператор NOT
!
в тесте оператора if
.
#!/бин/баш если [[ ! -d $1 ]] тогда echo "Создание резервного каталога:" $1 мкдир $1 если [[ ! $? -экв 0 ]] тогда echo "Не удалось создать резервный каталог:" $1 выход фи еще echo "Резервный каталог существует." фи # продолжить резервное копирование файла echo "Резервное копирование в: "$1
Если каталог не существует, он создает его. Если файлы создания каталога, скрипт завершает работу. Если каталог создан успешно или каталог уже существует, сценарий продолжает выполнять действия по резервному копированию.
Мы запустим сценарий, а затем проверим с помощью ls
и опции -d
(каталог), существует ли резервный каталог.
./script6.sh Документы/проект-резервная копия
ls -d Документы/проект-резервная копия
Резервный каталог создан. Если мы снова запустим скрипт, он должен сообщить, что каталог уже существует.
./script6.sh
Сценарий находит каталог и переходит к выполнению резервного копирования.
Тестируйте, не предполагайте
Рано или поздно предположения приведут к плохим последствиям. Сначала протестируйте и реагируйте соответственно.
Знание - сила. Используйте тесты, чтобы дать вашим скриптам необходимые знания.
СВЯЗАННЫЕ С: Как позволить сценариям Linux обнаруживать, что они работают на виртуальных машинах