Bash если файл не пустой
Часто при написании сценариев оболочки вы можете оказаться в ситуации, когда вам нужно выполнить действие в зависимости от того, существует файл или нет.
В Bash вы можете использовать команду test, чтобы проверить, существует ли файл, и определить тип файла.
Команда test принимает одну из следующих синтаксических форм:
Если вы хотите, чтобы ваш сценарий был переносимым, вам следует предпочесть старую команду test [ , которая доступна во всех оболочках POSIX. Новая обновленная версия тестовой команды [[ (двойные скобки) поддерживается в большинстве современных систем, использующих Bash, Zsh и Ksh в качестве оболочки по умолчанию.
Проверьте, существует ли файл
При проверке существования файла наиболее часто используются операторы FILE -e и -f . Первый проверит, существует ли файл независимо от типа, а второй вернет истину, только если ФАЙЛ является обычным файлом (а не каталогом или устройством).
Если вы хотите выполнить другое действие в зависимости от того, существует файл или нет, просто используйте конструкцию if / then:
Всегда используйте двойные кавычки, чтобы избежать проблем при работе с файлами, в именах которых есть пробелы.Если вы хотите запустить серию команд после оператора && просто заключите команды в фигурные скобки, разделенные ; или && :
Напротив && , оператор после || Оператор будет выполняться только в том случае, если статус выхода тестовой команды false .
Проверить, существует ли каталог
Операторы -d позволяют вам проверить, является ли файл каталогом или нет.
Например, чтобы проверить, существует ли каталог /etc/docker вы должны использовать:
Вы также можете использовать двойные скобки [[ вместо одинарной [ .
Проверьте, не существует ли файла
Как и во многих других языках, тестовое выражение может быть отменено с помощью ! (восклицательный знак) оператор логического НЕ:
То же, что и выше:
Проверьте, существует ли несколько файлов
Вместо использования сложных вложенных конструкций if / else вы можете использовать -a (или && с [[ ), чтобы проверить, существует ли несколько файлов:
Эквивалентные варианты без использования оператора IF:
Операторы проверки файлов
Команда test включает в себя следующие операторы FILE, которые позволяют проверять файлы определенных типов:
Выводы
В этом руководстве мы показали вам, как проверить, существует ли файл или каталог в Bash.
Если у вас есть какие-либо вопросы или отзывы, не стесняйтесь оставлять комментарии.
Этот ключ может использоваться для проверки -- является ли файл стандартным устройством ввода stdin ( [ -t 0 ]) или стандартным устройством вывода stdout ( [ -t 1 ]).
файл доступен для чтения ( пользователю, запустившему сценарий )
файл доступен для записи (пользователю, запустившему сценарий)
файл доступен для исполнения (пользователю, запустившему сценарий)
set-group-id (sgid) флаг для файла или каталога установлен
Если для каталога установлен флаг sgid, то файлы, создаваемые в таком каталоге, наследуют идентификатор группы каталога, который может не совпадать с идентификатором группы, к которой принадлежит пользователь, создавший файл. Это может быть полезно для каталогов, в которых хранятся файлы, общедоступные для группы пользователей.
set-user-id (suid) флаг для файла установлен
Установленный флаг suid приводит к изменению привилегий запущенного процесса на привилегии владельца исполняемого файла. Исполняемые файлы, владельцем которых является root , с установленным флагом set-user-id запускаются с привилегиями root , даже если их запускает обычный пользователь. [1] Это может оказаться полезным для некоторых программ (таких как pppd и cdrecord), которые осуществляют доступ к аппаратной части компьютера. В случае отсутствия флага suid , программы не смогут быть запущены рядовым пользователем, не обладающим привилегиями root.
Файл с установленным флагом suid отображается с включенным флагом s в поле прав доступа.
флаг sticky bit (бит фиксации) установлен
Общеизвестно, что флаг "sticky bit" -- это специальный тип прав доступа к файлам. Программы с установленным флагом "sticky bit" остаются в системном кэше после своего завершения, обеспечивая тем самым более быстрый запуск программы. [2] Если флаг установлен для каталога, то это приводит к ограничению прав на запись. Установленный флаг "sticky bit" отображается в виде символа t в поле прав доступа.
Если пользователь не является владельцем каталога, с установленным "sticky bit", но имеет право на запись в каталог, то он может удалять только те файлы в каталоге, владельцем которых он является. Это предотвращает удаление и перезапись "чужих" файлов в общедоступных каталогах, таких как /tmp.
вы являетесь владельцем файла
вы принадлежите к той же группе, что и файл
файл был модифицирован с момента последнего чтения
файлы f1 и f2 являются "жесткими" ссылками на один и тот же файл
"НЕ" -- логическое отрицание (инверсия) результатов всех вышеприведенных проверок (возвращается true если условие отсутствует).
Пример 7-4. Проверка "битых" ссылок
Примечания
С флагом suid , на двоичных исполняемых файлах, надо быть очень осторожным, поскольку это может быть небезопасным. Установка флага suid на файлы-сценарии не имеет никакого эффекта.
В современных UNIX-системах, "sticky bit" больше не используется для файлов, только для каталогов.
Я использовал следующий скрипт, чтобы проверить, существует ли файл:
Какой правильный синтаксис использовать, если я только хочу проверить, существует ли файл не ?
Команда тест ( [ здесь) имеет «не» логический оператор, который является восклицательным знаком (аналогично многим другим языкам). Попробуйте это:
Тестирование файлов Bash
-b filename - заблокировать специальный файл
-c filename - файл специальных символов
-d directoryname - проверка существования каталога
-e filename - Проверить существование файла независимо от его типа (узел, каталог, сокет и т. Д.)
-f filename - проверка на наличие обычного файла, а не каталога
-G filename - проверка, существует ли файл и принадлежит ли он эффективный идентификатор группы
-G filename set-group-id - True, если файл существует и является идентификатором группы-набора
-k filename - Sticky bit
-L filename - Символическая ссылка
---- +: = 9 =: + ---- - True, если файл существует и принадлежит действующему идентификатору пользователя
-O filename - проверить, доступен ли файл для чтения.
-r filename - проверить, является ли файл сокетом
-S filename - проверить, не равен ли файл ненулевому размеру
-s filename - проверьте, установлен ли бит набора идентификаторов пользователя
-u filename - проверить, доступен ли файл для записи
-w filename - проверить, является ли файл исполняемым
Как использовать:
Вы можете отменить выражение с помощью "!":
Соответствующей справочной страницей является man test или, что эквивалентно, man [ - или help test или help [ для встроенной команды bash.
Также возможно, что файл является неработающей символической ссылкой или нерегулярным файлом, например, например. розетка, устройство или fifo. Например, чтобы добавить проверку на битые символические ссылки:
Стоит отметить, что если вам нужно выполнить одну команду, вы можете сократить
Я предпочитаю использовать следующий однострочный текст в формате, совместимом с POSIX :
Для пары команд, как я сделал бы в сценарии:
Как только я начал это делать, я уже редко использую полностью типизированный синтаксис !!
Чтобы проверить существование файла, параметр может быть одним из следующих:
Все приведенные ниже тесты применимы к обычным файлам, каталогам и символическим ссылкам:
Будьте осторожны с запуском test для переменной без кавычек, поскольку это может привести к неожиданным результатам:
Рекомендуется, чтобы проверяемая переменная была заключена в двойные кавычки:
Вы можете сделать это:
Если вы хотите проверить оба файла и папки, используйте -e вместо -f . -e возвращает true для обычных файлов, каталогов, сокетов, специальных символов, блокированных специальных файлов и т. д.
Есть три различных способа сделать это:
Отмените статус выхода с помощью bash (другой ответ не сказал этого):
Действуйте, чтобы результат теста был отрицательным ( || вместо && ):
Это выглядит глупо (IMO), не используйте его, если ваш код не должен переноситься на оболочку Bourne (например, /bin/sh Solaris 10 или более ранней версии), в котором отсутствовал оператор отрицания конвейера ( ! ):
команда [ выполняет команду stat() (не lstat() ) системный вызов для пути, сохраненного в $file и возвращает true , если этот системный вызов завершился успешно, и тип файла, возвращаемый stat() является "регулярным".
Таким образом, если [ -f "$file" ] возвращает true, вы можете сказать, что файл существует и является обычным файлом или символической ссылкой, в конечном итоге преобразующейся в обычный файл (или, по крайней мере, это было во время stat() ).
Однако, если он возвращает false (или если [ ! -f "$file" ] или ! [ -f "$file" ] верните true), есть много разных возможностей:
- файл не существует
- файл существует, но не является обычным файлом
- файл существует, но у вас нет разрешения на поиск в родительском каталоге
- файл существует, но путь к нему слишком длинный
- файл является символической ссылкой на обычный файл, но у вас нет разрешения на поиск в некоторых каталогах, связанных с разрешением символической ссылки.
- . любая другая причина, по которой системный вызов stat() может завершиться неудачей.
Короче говоря, это должно быть:
Чтобы точно знать, что файл не существует, нам потребуется системный вызов stat() для возврата с кодом ошибки ENOENT ( ENOTDIR говорит нам об одном из Компоненты пути не каталог, это другой случай, когда мы можем сказать, что файл не существует по этому пути). К сожалению, команда [ не сообщает нам об этом. Он вернет false, независимо от того, является ли код ошибки ENOENT, EACCESS (разрешение отклонено), ENAMETOOLONG или что-то еще.
Тест [ -e "$file" ] также можно выполнить с помощью ls -Ld -- "$file" > /dev/null . В этом случае ls расскажет вам, почему stat() не удалось, хотя информация не может быть легко использована программно:
По крайней мере ls говорит мне, что это не потому, что файл не существует, потому что он выходит из строя. Это потому, что он не может определить, существует файл или нет. Команда [ просто проигнорировала проблему.
С помощью оболочки zsh вы можете запросить код ошибки с помощью $ERRNO специальная переменная после неудачной команды [ и декодировать это число с помощью $errnos специальный массив в модуле zsh/system :
Чтобы отменить тест, используйте «!». Это эквивалентно «не» логическому оператору в других языках. Попробуйте это:
[ — является специальной встроенной командой test воспринимающей свои аргументы как выражение сравнения или файловую проверку […..].
[[ — расширенный вариант от «[«, является зарезервированным словом, а не командой, его bash выполняет как один элемент с кодом возврата. Внутри «[[….]]» разрешается выполнение операторов &&, || которые приводят к ошибке в обычных скобках «[….]» тем самым вариант с двойной скобкой более универсален.
(( — является арифметическими выражениями, которое так же возвращают код 0. Тем самым такие выражения могут участвовать в операциях сравнения.
Приведу список логических операторов, которые используются для if|then|else:
-z – строка пуста
-n – строка не пуста
=, ( == ) – строки равны
!= – строки неравны
-eq – равно
-ne – неравно
-lt,(< ) – меньше
-le,(<=) – меньше или равно
-gt,(>) – больше
-ge,(>=) - больше или равно
! - отрицание логического выражения
-a,(&&) – логическое «И»
-o,(||) -логическое «ИЛИ»
Конструкции простой проверки if|then
Другими словами:
если проверяемое_выражение_или_команды_верны; то выполняем команды закрываем если
Пример 1
Часто встречается в скриптах проверка — «существует ли файлы или каталоги» на их примере покажу работу
Пример 2
Пример 3
&& - логическое «и», если первый путь «истина» проверяем второй, если он тоже «истина», то выполняем команды (echo)
-f – ключ проверки на существования файла (о них чуть ниже)
Конструкции простой проверки if|then|else
если проверяемое_выражение_или_команды_верны; то команды 1 иначе команды 2 закрываем если
Пример 4
Возможно не лучший пример, нас интересует именно ответ 0 или 1. В результате печатается в консоль «Тест» и «0» потому что команда «echo Тест» успешна и это «истина».
Примеры «существуют ли файл?»
Пример 5
Если файл bashrc существует, то печатает в консоль «Файл существует!», иначе печатает «Файл не существует!»
Поиграйте с именем проверяемого файла
Пример 6
Ключи к файлам и каталогам
[ -ключ “путь” ]
[ -e “путь каталогу_или_файлу”] – существует ли файл или каталог.
[ -r “путь к файлу/каталогу”] – доступен ли файл/каталог для чтения.
[ -f “путь к файлу/каталогу”] – существует ли файл.
[ -d “путь к каталогу”] – существует ли каталог.
Полное описание возможных применений различных скобок, правильное расставление кавычек уходит далеко от темы, поэтому могу посоветовать обратится к руководству Advanced Bash Scripting
Арифметика
Пример 7
Если оператор > использовать внутри [[….]], он рассматривается как оператор сравнения строк, а не чисел. Поэтому операторам > и < для сравнения чисел лучше заключить в круглые скобки.
Используем круглые скобки для математического сравнение. Если «3» меньше «6» печатаем «Да».
Пример 8
Использование команды test, коей являются квадратные скобки. Если «3» меньше «6» печатаем «Да».
Можно использовать и двойные квадратные скобки, это расширенный вариант команды test, эквивалентом которой является «[ ]». Если «3» меньше «6» печатаем «Да».
Пример 9
Используем двойные квадратные скобки, потому что применяем оператор «&&». Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если оно тоже 2=2 (истина), печатаем «Верно»
Если первое выражение 2 = 2 (истина) тогда выполняем второе, и если переменная «b» не равна двум (ложь), печатаем «Не верно»
Можно конечно сделать проще, нам главное понять принцип if|then и else, не стесняйтесь менять, подставляя свои значения.
Вложение нескольких проверок
Bash позволяет вкладывать в блок несколько блоков
Построения многоярусных конструкций
Для построения многоярусных конструкции, когда необходимо выполнять множество проверок лучше использовать elif — это краткая форма записи конструкции else if.
Читайте также: