Я использовал следующий script, чтобы увидеть, существует ли файл:
#!/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
Команда test ([
здесь) имеет "не" логический оператор, который является восклицательным знаком (подобно многим другим языки). Попробуйте следующее:
if [ ! -f /tmp/foo.txt ]; then
echo "File not found!"
fi
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!"
Bash Тестирование файлов
-b filename
- Заблокировать специальный файл -c filename
- Файл специального символа -d directoryname
- Проверить каталог Существование -e filename
- Проверить наличие файла, независимо от типа (node, directory, socket и т.д.) -f filename
- Проверить наличие обычного файла, а не каталог -G filename
- Проверьте, существует ли файл и принадлежит ли он эффективному идентификатору группы -G filename set-group-id
- Истина, если файл существует и задан как set-group-id -k filename
- Липкий бит -L filename
- Символическая ссылка -O filename
- Истина, если файл существует и принадлежит эффективному идентификатору пользователя -r filename
- Проверьте, является ли файл доступным для чтения
-S filename
- Проверьте, является ли файл socket
-S filename
- Проверьте, не является ли файл ненулевым размером -u filename
- Проверьте, установлен ли бит файла set-user-id
-w filename
- Проверьте, доступен ли файл для записи -x filename
- проверить, является ли файл исполняемым
Как использовать:
#!/bin/bash
file=./file
if [ -e "$file" ]; then
echo "File exists"
else
echo "File does not exist"
fi
Тестовое выражение можно отрицать с помощью оператора !
#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
echo "File does not exist"
else
echo "File exists"
fi
-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
Вы можете отменить выражение с помощью "!":
#!/bin/bash
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist"
fi
Соответствующая справочная страница man test
или, эквивалентно, man [
- или help test
или help [
для встроенной команды bash.
[
встроен. Таким образом, релевантная информация скорее получена с help [
... но это показывает, что [
является синонимом встроенного test
, следовательно, релевантная информация скорее получена с help test
. См. Также раздел «Условные выражения Bash» в руководстве .
[
ведет себя очень похоже на команду external [
, поэтому либо команда man test
либо man [
даст вам хорошее представление о том, как она работает.
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
Кроме того, возможно, что файл является сломанной символической ссылкой или нерегулярным файлом, например, например. сокет, устройство или fifo. Например, чтобы добавить проверку для сломанных символических ссылок:
if [[ ! -f $FILE ]]; then
if [[ -L $FILE ]]; then
printf '%s is a broken symlink!\n' "$FILE"
else
printf '%s does not exist!\n' "$FILE"
fi
fi
Стоит отметить, что если вам нужно выполнить одну команду, вы можете сокращать
if [ ! -f "$file" ]; then
echo "$file"
fi
к
test -f "$file" || echo "$file"
или
[ -f "$file" ] || echo "$file"
Я предпочитаю делать следующий однострочный шрифт в POSIX формате, совместимом с оболочкой:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
Для нескольких команд, как я бы сделал в script:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
Как только я начал делать это, я редко использую полностью типизированный синтаксис больше!
test
[
или 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).
Чтобы проверить существование файла, параметр может быть любым из следующих:
-e: Returns true if file exists (regular file, directory, or symlink)
-f: Returns true if file exists and is a regular file
-d: Returns true if file exists and is a directory
-h: Returns true if file exists and is a symlink
Все приведенные ниже тесты применяются к обычным файлам, каталогам и символическим ссылкам:
-r: Returns true if file exists and is readable
-w: Returns true if file exists and is writable
-x: Returns true if file exists and is executable
-s: Returns true if file exists and has a size > 0
Пример script:
#!/bin/bash
FILE=$1
if [ -f "$FILE" ]; then
echo "File $FILE exists"
else
echo "File $FILE does not exist"
fi
Вы должны быть осторожны при запуске test
для некотируемой переменной, поскольку это может привести к неожиданным результатам:
$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1
Обычно рекомендуется, чтобы тестируемая переменная была окружена двойными кавычками:
#!/bin/sh
FILE=$1
if [ ! -f "$FILE" ]
then
echo "File $FILE does not exist."
fi
Существует три различных способа сделать это:
Отмените статус выхода с помощью bash (ни один другой ответ не сказал об этом):
if ! [ -e "$file" ]; then
echo "file does not exist"
fi
Или:
! [ -e "$file" ] && echo "file does not exist"
Отмените тест внутри тестовой команды [
(таким образом, как большинство ответов до этого было представлено):
if [ ! -e "$file" ]; then
echo "file does not exist"
fi
Или:
[ ! -e "$file" ] && echo "file does not exist"
Акт о том, что результат теста отрицательный (||
вместо &&
):
только
[ -e "$file" ] || echo "file does not exist"
Это выглядит глупо (IMO), не используйте его, если ваш код не должен быть переносимым в оболочку Bourne (например, /bin/sh
Solaris 10 или более ранней версии), в которой не было оператора отрицания конвейера (!
):
if [ -e "$file" ]; then
:
else
echo "file does not exist"
fi
! [
и [ !
?
! [
это 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, и, по моему опыту, оба широко поддерживаются.
В
[ -f "$file" ]
команда [
выполняет системный вызов stat()
(not lstat()
) в пути, хранящемся в $file
, и возвращает true, если этот системный вызов завершается успешно, а тип файла, возвращаемый stat()
, - это "Стабильный".
Итак, если [ -f "$file" ]
возвращает true, вы можете сказать, что файл существует и является обычным файлом или символической ссылкой, в конечном итоге разрешающей обычный файл (или, по крайней мере, это было во время stat()
).
Однако, если он возвращает false (или если [ ! -f "$file" ]
или ! [ -f "$file" ]
возвращает true), существует много разных возможностей:
stat()
может выйти из строя.Короче говоря, это должно быть:
if [ -f "$file" ]; then
printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
elif [ -e "$file" ]; then
printf '"%s" exists but is not a regular file\n' "$file"
elif [ -L "$file" ]; then
printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
else
printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
fi
Чтобы точно знать, что файл не существует, нам понадобится системный вызов stat()
для возврата с кодом ошибки ENOENT
(ENOTDIR
говорит нам, что один из компонентов пути не является каталогом это еще один случай, когда мы можем сказать, что файл не существует по этому пути). К сожалению, команда [
не сообщает об этом. Он вернет false, является ли код ошибки ENOENT, EACCESS (разрешение отклонено), ENAMETOOLONG или что-то еще.
Тест [ -e "$file" ]
также можно выполнить с помощью ls -Ld -- "$file" > /dev/null
. В этом случае ls
расскажет вам, почему сбой stat()
, хотя информация не может быть легко использована программно:
$ file=/var/spool/cron/crontabs/root
$ if [ ! -e "$file" ]; then echo does not exist; fi
does not exist
$ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
stat failed
По крайней мере ls
говорит мне об этом не потому, что файл не существует, что он терпит неудачу. Это потому, что он не может определить, существует ли файл или нет. Команда [
просто проигнорировала проблему.
С помощью оболочки zsh
вы можете запросить код ошибки с помощью специальной переменной $ERRNO
после команды [
и декодировать это число с помощью специального массива $errnos
в модуле zsh/system
:
zmodload zsh/system
ERRNO=0
if [ ! -f "$file" ]; then
err=$ERRNO
case $errnos[err] in
("") echo exists, not a regular file;;
(ENOENT|ENOTDIR)
if [ -L "$file" ]; then
echo broken link
else
echo does not exist
fi;;
(*) echo "can't tell"; syserror "$err"
esac
fi
(остерегайтесь поддержки $errnos
в некоторых версиях zsh
при построении с последними версиями gcc
).
Этот код также работает.
#!/bin/bash
FILE=$1
if [ -f $FILE ]; then
echo "File '$FILE' Exists"
else
echo "The File '$FILE' Does Not Exist"
fi
Чтобы отменить тест, используйте "!". Это эквивалентно "не" логическому оператору на других языках. Попробуйте следующее:
if [ ! -f /tmp/foo.txt ];
then
echo "File not found!"
fi
Или написано несколько иначе:
if [ ! -f /tmp/foo.txt ]
then echo "File not found!"
fi
Или вы могли бы использовать:
if ! [ -f /tmp/foo.txt ]
then echo "File not found!"
fi
Или, все вместе:
if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
Что может быть написано (используя оператор "и": & &) как:
[ ! -f /tmp/foo.txt ] && echo "File not found!"
Который выглядит короче:
[ -f /tmp/foo.txt ] || echo "File not found!"
Вещь test
может засчитываться. Это сработало для меня (на основе Bash Shell: Проверить наличие файла или нет):
test -e FILENAME && echo "File exists" || echo "File doesn't exist"
Вы можете использовать Bash specific:
[[ ! -f "$FILE" ]] && echo "File doesn't exist"
или
if [[ ! -f "$FILE" ]]; then
echo "File doesn't exist"
fi
Если вы хотите проверить файл и папку обоими, используйте опцию -e
вместо -f
.
[
полезностью здесь.
-f
) и каталоги - это только два из многих типов файлов . Существуют также сокеты, символические ссылки, устройства, fifos, doors ... [ -e
проверит наличие файлов (любого типа, включая обычный, fifo, directory ...) после разрешения символической ссылки .
Самый простой способ
FILE=$1
[ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
Эта оболочка script также работает для поиска файла в каталоге:
echo "enter file"
read -r a
if [ -s /home/trainee02/"$a" ]
then
echo "yes. file is there."
else
echo "sorry. file is not there."
fi
read -p "Enter file name: " -ra
для запроса, а также для чтения. Он использует кавычки вокруг переменной; это хорошо, но должно быть объяснено. Было бы лучше, если бы он повторял имя файла. И это проверяет, что файл существует и не является пустым (это означает -s
), тогда как вопрос задает любой файл, пустой или нет (для которого -f
более подходит).
иногда бывает удобно использовать && и || операторы.
Как и в (если у вас есть команда "test" ):
test -b $FILE && echo File not there!
или
test -b $FILE || echo File there!
if [ -f $FILE ]; then; else; echo "File $FILE does not exist."; fi;
Наверное, хорошо, что вместо этого я нашел этот вопрос и научился делать это более правильно. :)