Я использовал следующий скрипт, чтобы увидеть, существует ли файл:
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File $FILE exists."
else
echo "File $FILE does not exist."
fi
Какой правильный синтаксис использовать, если я только хочу проверить, не существует ли файл ?
#!/bin/bash
FILE=$1
if [ $FILE does not exist ]; then
echo "File $FILE does not exist."
fi
if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;
Вероятно, хорошо, что вместо этого я нашел этот вопрос и научился делать его более правильным образом. :)-e
. -f не будет забирать каталоги, символическиеFILE=$1
->FILE="$1"
иif [ -f $FILE ];
->if [ -f "$FILE" ];
Ответы:
Команда test (
[
здесь) имеет «не» логический оператор, который является восклицательным знаком (аналогично многим другим языкам). Попробуй это:источник
if [ ! \( -f "f1" -a -f "f2" \) ] ; then echo MISSING; fi
if [ ! -f "f1" ] || [ ! -f "f2" ] ; then echo MISSING; fi
[ -f /tmp/foo.txt ] || echo "File not found!"
-e: Returns true value, if file exists
-f: Return true value, if file exists and regular file
-r: Return true value, if file exists and is readable
-w: Return true value, if file exists and is writable
-x: Return true value, if file exists and is executable
-d: Return true value, if exists and is a directory
! -f
с по&&
сравнению с использованием-f
с||
. Это связано с кодом выхода, возвращаемым проверкой отсутствия / существования. Если вам нужно, чтобы ваша строка всегда корректно выходила с кодом выхода 0 (а иногда вам не нужно это ограничение), эти два подхода не являются взаимозаменяемыми. В качестве альтернативы, просто используйтеif
оператор, и вам больше не нужно беспокоиться о коде завершения вашей проверки не / существования.Тестирование файлов Bash
-b filename
- Блокировать специальный файл-c filename
- Файл специальных символов-d directoryname
- Проверить наличие каталога-e filename
- Проверить существование файла, независимо от его типа (узел, каталог, сокет и т. Д.)-f filename
- Проверить наличие файла в обычном режиме, а не каталог-G filename
- Проверить, существует ли файл и принадлежит ли он эффективный идентификатор группы-G filename set-group-id
- Истинно, если файл существует и задан идентификатором группы-k filename
- Закрепленный бит-L filename
- Символическая ссылка-O filename
- Истинно, если файл существует и принадлежит эффективному идентификатору пользователя-r filename
- Проверить, доступен ли файл для чтения-S filename
- Проверить, является ли файл сокетом-s filename
- Проверить размер файла не равен нулю-u filename
- проверьте, установлен ли бит set-user-id-w filename
файла-x filename
- проверьте, доступен ли файл для записи - проверьте, является ли файл исполняемымКак пользоваться:
Проверяемое выражение может быть сведено на нет с помощью
!
оператораисточник
-n String
- Проверьте, не равна ли длина строки нулю. Или вы имеете в видуfile1 -nt file2
- Проверьте, является ли file1 более новым, чем файл 2 (вы также можете использовать -ot для более старшего)The unary operator -z tests for a null string, while -n or no operator at all returns True if a string is not empty.
~ ibm.com/developerworks/library/l-bash-test/index.htmlВы можете отменить выражение с помощью "!":
Соответствующей страницей руководства является
man test
или, что эквивалентно,man [
- илиhelp test
илиhelp [
для встроенной команды bash.источник
[
это встроенный. Таким образом, соответствующая информация скорее получаетсяhelp [
... но это показывает, что[
это синонимtest
встроенного, следовательно, соответствующая информация скорее получаетсяhelp test
. См. Также раздел «Условные выражения Bash» в руководстве .[
команда bash ведет себя очень похоже на внешнюю[
команду, так что либо она,man test
либоman [
даст вам хорошее представление о том, как она работает.[
имеет больше переключателей, чем внешняя команда,[
найденная в моей системе ... Вообще говоря, я считаю, что лучше читать документацию, относящуюся к конкретному инструменту, а не документацию, относящуюся к другому неопределенно связанному. Хотя я могу ошибаться;)
Также возможно, что файл является неработающей символической ссылкой или нестандартным файлом, например, сокетом, устройством или fifo. Например, чтобы добавить проверку на битые символические ссылки:
источник
Стоит отметить, что если вам нужно выполнить одну команду, вы можете сократить
в
или
источник
Я предпочитаю делать следующий однострочник в формате, совместимом с POSIX :
Для пары команд, как я сделал бы в сценарии:
Как только я начал это делать, я уже редко использую полностью типизированный синтаксис !!
источник
[
илиtest
будет проверять наличие аргумента по умолчанию в файле (в отличие от-e
)? Разве это не было бы двусмысленным? AFAIK (и AIUI в разделе «УСЛОВНЫЕ ВЫРАЖЕНИЯ») единственное, что проверяется вашим подходом, это то, что аргумент не является пустым (или неопределенным), что в данном случае является тавтологией (пусть$DIR = ''
и$FILE = ''
, тогда аргумент все еще'//'
).ls /foo
результатls: cannot access /foo: No such file or directory
.[ /foo ] && echo 42
, результат42
. GNU bash, версия 4.2.37 (1) -релиз (i486-pc-linux-gnu).-f
опцию, в данный момент я написал этот ответ. Очевидно, вы всегда можете использовать-e
, если вы не уверены, что это будет обычный файл. Кроме того, во всех моих сценариях я цитирую эти конструкции, я, должно быть, только что представил это без адекватного подтверждения.[ $condition ] && if_true || if_false
подвержена ошибкам. В любом случае мне[ ! -f "$file" ] && if_not_exists
легче читать и понимать, чем[ -f "$file" ] || if_not_exists
.Чтобы проверить существование файла, параметр может быть любым из следующих:
Все приведенные ниже тесты применяются к обычным файлам, каталогам и символическим ссылкам:
Пример скрипта:
источник
Ты можешь сделать это:
или
Если вы хотите проверить оба файла и папки, используйте
-e
параметр вместо-f
.-e
возвращает true для обычных файлов, каталогов, сокетов, специальных файлов символов, блокировки специальных файлов и т. д.источник
[
утилитой.-f
) и каталоги - это только два из множества различных типов файлов . Существуют также сокеты, символические ссылки, устройства, fifos, doors ..., которые[ -e
будут проверять наличие файлов (любого типа, включая обычный, fifo, directory ...) после разрешения символической ссылки .-e
, он нужен-f
.Вы должны быть осторожны при запуске
test
переменной без кавычек, потому что это может привести к неожиданным результатам:Обычно рекомендуется, чтобы проверяемая переменная была заключена в двойные кавычки:
источник
[ ... ]
.Есть три различных способа сделать это:
Отмените статус выхода с помощью bash (другой ответ не сказал этого):
Или:
Отмените тест внутри команды test
[
(именно так было представлено большинство ответов):Или:
Действуйте, чтобы результат теста был отрицательным (
||
вместо&&
):Только:
Это выглядит глупо (IMO), не используйте его, если ваш код не должен быть переносимым на оболочку Bourne (как в
/bin/sh
Solaris 10 или более ранней версии), в которой отсутствует оператор отрицания конвейера (!
):источник
! [
и[ !
?! [
POSIX для конвейеров оболочки 2.9.2 (любая команда)Otherwise, the exit status shall be the logical NOT of the exit status of the last command
и[ !
POSIX для тестирования.! expression True if expression is false. False if expression is true.
Итак, оба являются POSIX, и, по моему опыту, оба широко поддерживаются.!
ключевого слова, которое было введено оболочкой Korn. За исключением, возможно, Solaris 10 и старше, вы вряд ли столкнетесь с оболочкой Bourne в эти дни.В
[
команда делаетstat()
(неlstat()
) системный вызов на пути , хранящегося в$file
и возвращает истинное если системный вызов завершается успешно и тип файла, возвращаемыйstat()
является « регулярным ».Таким образом, если
[ -f "$file" ]
возвращает true, вы можете сказать, что файл существует и является обычным файлом или символической ссылкой, в конечном итоге преобразующейся в обычный файл (или, по крайней мере, это было во времяstat()
).Однако, если он вернется false (или if
[ ! -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
модуле:(имейте в виду, что
$errnos
поддержка была нарушена в некоторых версиях,zsh
когда они были собраны с последними версиямиgcc
).источник
Чтобы отменить тест, используйте «!». Это эквивалентно «не» логическому оператору в других языках. Попробуй это:
Или написано немного по-другому:
Или вы можете использовать:
Или, давя все вместе:
Который может быть записан (используя оператор «и»: &&) как:
Который выглядит короче, как это:
источник
Эта
test
вещь тоже может рассчитывать. Это сработало для меня (на основе Bash Shell: Проверить наличие файла или нет ):источник
Этот код также работает.
источник
Самый простой способ
источник
Этот сценарий оболочки также работает для поиска файла в каталоге:
источник
read -p "Enter file name: " -r a
для подсказки, так и для чтения. Он использует кавычки вокруг переменной; это хорошо, но должно быть объяснено. Возможно, было бы лучше, если бы оно повторяло имя файла. И это проверяет, что файл существует и не является пустым (в этом смысл-s
), тогда как вопрос касается любого файла, пустого или нет (для которого-f
более уместно).иногда может быть удобно использовать && и || операторы.
Как в (если у вас есть команда «тест»):
или
источник
Если вы хотите использовать
test
вместо[]
, то вы можете использовать,!
чтобы получить отрицание:источник
Вы также можете сгруппировать несколько команд в один вкладыш
[ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )
или
[ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}
Если имя файла не выходит, вывод будет
Примечание: (...) работает в подоболочке, {...;} работает в той же оболочке.
Запись в фигурных скобках работает только в bash.источник
источник