Как мне узнать, что обычный файл не существует в Bash? - PullRequest
2938 голосов
/ 12 марта 2009

Я использовал следующий скрипт, чтобы проверить, существует ли файл:

#!/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

Ответы [ 18 ]

4142 голосов
/ 12 марта 2009

Команда test (здесь [) имеет "не" логический оператор, который является восклицательным знаком (аналогично многим другим языкам). Попробуйте это:

if [ ! -f /tmp/foo.txt ]; then
    echo "File not found!"
fi
581 голосов
/ 16 января 2014

Тестирование файлов Bash

-b filename - Блокировать специальный файл
-c filename - файл специальных символов
-d directoryname - Проверить наличие каталога
-e filename - проверка существования файла независимо от типа (узел, каталог, сокет и т. Д.)
-f filename - Проверить наличие обычного файла, а не каталога
-G filename - Проверить, существует ли файл и принадлежит ли ему эффективный идентификатор группы
-G filename set-group-id - Истинно, если файл существует и является set-group-id
-k filename - Липкий бит
-L filename - Символическая ссылка
-O filename - Истинно, если файл существует и принадлежит эффективному идентификатору пользователя
-r filename - Проверить, доступен ли файл для чтения
-S filename - Проверить, является ли файл сокетом
-s filename - Проверить, не равен ли файл ненулевому размеру
-u filename - Проверить, установлен ли бит набора идентификаторов пользователя
-w filename - Проверить, доступен ли файл для записи
-x filename - Проверить, является ли файл исполняемым

Как использовать:

#!/bin/bash
file=./file
if [ -e "$file" ]; then
    echo "File exists"
else 
    echo "File does not exist"
fi 

A тестовое выражение может быть отменено с помощью оператора !

#!/bin/bash
file=./file
if [ ! -e "$file" ]; then
    echo "File does not exist"
else 
    echo "File exists"
fi 
274 голосов
/ 12 марта 2009

Вы можете отменить выражение с помощью "!":

#!/bin/bash
FILE=$1

if [ ! -f "$FILE" ]
then
    echo "File $FILE does not exist"
fi

Соответствующей справочной страницей является man test или, что эквивалентно, man [ - или help test или help [ для встроенной команды bash.

126 голосов
/ 12 марта 2009
[[ -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
91 голосов
/ 11 августа 2011

Стоит отметить, что если вам нужно выполнить одну команду, вы можете сократить

if [ ! -f "$file" ]; then
    echo "$file"
fi

до

test -f "$file" || echo "$file"

или

[ -f "$file" ] || echo "$file"
64 голосов
/ 18 октября 2011

Я предпочитаю делать следующие однострочные, в POSIX совместимый формат оболочки:

$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"

$ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"

Для пары команд, как я сделал бы в сценарии:

$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}

Как только я начал это делать, я уже редко использую полностью типизированный синтаксис !!

48 голосов
/ 19 декабря 2013

Чтобы проверить существование файла, параметр может быть любым из следующих:

-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

Пример сценария:

#!/bin/bash
FILE=$1

if [ -f "$FILE" ]; then
   echo "File $FILE exists"
else
   echo "File $FILE does not exist"
fi
33 голосов
/ 28 апреля 2015

Вы можете сделать это:

[[ ! -f "$FILE" ]] && echo "File doesn't exist"

или

if [[ ! -f "$FILE" ]]; then
    echo "File doesn't exist"
fi

Если вы хотите проверить оба файла и папки, используйте параметр -e вместо -f. -e возвращает true для обычных файлов, каталогов, сокетов, специальных символов, блокированных специальных файлов и т. Д.

31 голосов
/ 24 января 2012

Вы должны быть осторожны при запуске test для переменной без кавычек, потому что это может привести к неожиданным результатам:

$ [ -f ]
$ echo $?
0
$ [ -f "" ]
$ echo $?
1

Обычно рекомендуется, чтобы проверяемая переменная была заключена в двойные кавычки:

#!/bin/sh
FILE=$1

if [ ! -f "$FILE" ]
then
   echo "File $FILE does not exist."
fi
22 голосов
/ 05 августа 2015

Есть три различных способа сделать это:

  1. Отрицание состояния выхода с помощью bash (другой ответ не сказал этого):

    if ! [ -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Или:

    ! [ -e "$file" ] && echo "file does not exist"
    
  2. Отменить тест внутри команды теста [ (именно так большинство ответов представили ранее):

    if [ ! -e "$file" ]; then
        echo "file does not exist"
    fi
    

    Или:

    [ ! -e "$file" ] && echo "file does not exist"
    
  3. Действуйте, если результат теста отрицательный (|| вместо &&):

    только

    [ -e "$file" ] || echo "file does not exist"
    

    Это выглядит глупо (IMO), не используйте его, если ваш код не должен быть переносимым на оболочку Bourne (например, /bin/sh в Solaris 10 или более ранней версии), в которой отсутствует оператор отрицания конвейера (!):

    if [ -e "$file" ]; then
        :
    else
        echo "file does not exist"
    fi
    
...