Проверьте, существует ли каталог в оболочке script

Какую команду можно использовать для проверки наличия или отсутствия каталога в оболочке script?

3026
задан 12 сент. '08 в 23:06
источник поделиться
34 ответов
  • 1
  • 2

Чтобы проверить, существует ли каталог в сценарии оболочки, вы можете использовать следующее:

if [ -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY exists.
fi

Или проверить, не существует ли директория:

if [ ! -d "$DIRECTORY" ]; then
  # Control will enter here if $DIRECTORY doesn't exist.
fi

Однако, как указывает Джон Эриксон, последующие команды могут не работать должным образом, если вы не принимаете во внимание, что символическая ссылка на каталог также пройдет эту проверку. Например, выполните следующие действия:

ln -s "$ACTUAL_DIR" "$SYMLINK"
if [ -d "$SYMLINK" ]; then 
  rmdir "$SYMLINK" 
fi

Появится сообщение об ошибке:

rmdir: failed to remove 'symlink': Not a directory

Таким образом, символические ссылки, возможно, придется обрабатывать по-разному, если последующие команды ожидают каталогов:

if [ -d "$LINK_OR_DIR" ]; then 
  if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here.
    rm "$LINK_OR_DIR"
  else
    # It a directory!
    # Directory command goes here.
    rmdir "$LINK_OR_DIR"
  fi
fi

Обратите особое внимание на двойные кавычки, используемые для переноса переменных, причина этого объясняется 8jean в другом ответе.

Если переменные содержат пробелы или другие необычные символы, это может привести к сбою сценария.

4173
ответ дан 12 сент. '08 в 23:07
источник

Не забудьте всегда переносить переменные в двойные кавычки, ссылаясь на них в a bash script. Дети в эти дни растут с идеей, что они могут иметь пробелы и множество других забавных персонажей в своих именах каталогов. (Пространства! В мои дни у нас не было никаких фантастических пространств!))

Однажды один из этих детей запустит ваш script с $DIRECTORY, установленным на "My M0viez", и ваш script взорвется. Вы этого не хотите. Поэтому используйте это.

if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists, even if it contains spaces
fi
455
ответ дан 16 сент. '08 в 1:00
источник

Обратите внимание, что тест -d может привести к неожиданным результатам:

$ ln -s tmp/ t
$ if [ -d t ]; then rmdir t; fi
rmdir: directory "t": Path component not a directory

Файл под: "Когда каталог не является каталогом?" Ответ: "Когда это символическая ссылка на каталог". Немного более тщательное испытание:

if [ -d t ]; then 
   if [ -L t ]; then 
      rm t
   else 
      rmdir t
   fi
fi

Дополнительную информацию в руководстве Bash можно найти в Bash условных выражениях и [ встроенная команда и [[ составная комм..

204
ответ дан 12 сент. '08 в 23:26
источник

Я нахожу версию с двумя скобками test делает естественные логические тесты написания:

if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
    echo "It a bona-fide directory"
fi
198
ответ дан 13 сент. '08 в 0:33
источник

Более короткая форма:

[ -d "$DIR" ] && echo "Yes"
125
ответ дан 13 сент. '08 в 0:08
источник

Чтобы проверить, существует ли каталог, вы можете использовать простую структуру, например:

if [ -d directory/path to a directory ] ; then
#Things to do

else #if needed #also: elif [new condition] 
# things to do
fi

Вы можете сделать это и в отрицательном

if [ ! -d directory/path to a directory ] ; then
# things to do when not an existing directory

Примечание. Будьте осторожны, оставляйте пустое пространство с обеих сторон обеих открывающих и закрывающих скобок.

С помощью того же синтаксиса вы можете использовать:

-e: any kind of archive 

-f: file 

-h: symbolic link 

-r: readable file 

-w: writable file 

-x: executable file 

-s: file size greater than zero 
119
ответ дан 08 апр. '15 в 5:50
источник
if [ -d "$DIRECTORY" ]; then  
    # Here if $DIRECTORY exists  
fi
94
ответ дан 15 апр. '14 в 11:07
источник

Вы можете использовать test -d (см. man test).

-d file Истина, если файл существует и является каталогом.

Например:

test -d "/etc" && echo Exists || echo Does not exist

Примечание. Команда test такая же, как условное выражение [ (см. man [), поэтому оно переносится по сценариям оболочки.

[ - Это синоним встроенного test, но последний аргумент должен быть буквальным ], чтобы соответствовать открытию [.

Для получения возможных вариантов или дополнительной помощи проверьте:

  • help [
  • help test
  • man test или man [
74
ответ дан 13 сент. '15 в 0:25
источник

Или для чего-то совершенно бесполезного:

[ -d . ] || echo "No"
54
ответ дан 17 авг. '09 в 17:02
источник

Здесь очень прагматичная идиома:

(cd $dir) || return # is this a directory,
                    # and do we have access?

Я обычно обертываю его в функцию:

can_use_as_dir() { 
    (cd ${1:?pathname expected}) || return
}

Или:

assert_dir_access() { 
    (cd ${1:?pathname expected}) || exit
}

Хорошая вещь об этом подходе заключается в том, что мне не нужно думать о хорошем сообщении об ошибке.

cd даст мне стандартное однострочное сообщение для stderr. Он также предоставит больше информации, чем я могу предоставить. Выполняя cd внутри подоболочки ( ... ), команда не влияет на текущий каталог вызывающего. Если каталог существует, эта подоболочка и функция просто не работают.

Далее приведен аргумент, который мы переходим к cd: ${1:?pathname expected}. Это более сложная форма замещения параметров, которая более подробно объясняется ниже.

Tl; dr: Если строка, переданная в эту функцию, пуста, мы снова выходим из подоболочки ( ... ) и возвращаемся от функции с данным сообщением об ошибке.


Цитата из справочной страницы ksh93:

${parameter:?word}

Если parameter установлено и не равно null, замените его значение; в противном случае напечатайте word и выйдите из оболочки (если не интерактивно). Если word опущено, выводится стандартное сообщение.

и

Если двоеточие : не указано в приведенных выше выражениях, shell проверяет, установлен ли параметр или нет.

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

В этом конкретном случае я знаю, что стандартное сообщение об ошибке 1: parameter not set недостаточно, поэтому я увеличиваю тип ожидаемого здесь значения - pathname каталога.

Философская заметка: Оболочка не является объектно-ориентированным языком, поэтому сообщение говорит pathname, а не directory. На этом уровне я бы предпочел сохранить его простым - аргументы функции являются просто строками.

46
ответ дан 10 авг. '12 в 0:43
источник
if [ -d "$Directory" -a -w "$Directory" ]
then
    #Statements
fi

Вышеприведенный код проверяет, существует ли каталог и доступен ли он.

35
ответ дан 21 апр. '10 в 9:06
источник

Введите этот код в bash promt

if [ -d "$DIRECTORY" ]; then
  # if true this block of code will execute
fi
24
ответ дан 05 нояб. '14 в 6:39
источник

Собственно, вы должны использовать несколько инструментов для получения пуленепробиваемого подхода:

DIR_PATH=`readlink -f "${the_stuff_you_test}"` # Get rid of symlinks and get abs path
if [[ -d "${DIR_PATH}" ]] ; Then # now you're testing
    echo "It a dir";
fi

Не нужно беспокоиться о пробелах и специальных символах, пока вы используете "${}".

Обратите внимание, что [[]] не так переносится, как [], но поскольку большинство людей работают с современными версиями Bash (поскольку в конце концов большинство людей даже не работают с командной строкой: -p), выгода больше, чем проблема.

19
ответ дан 17 февр. '10 в 20:46
источник

Дополнительные функции с использованием find

  • Проверьте наличие папки в подкаталогах:

    found=`find -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where "myDirectory" is.
        # It may contain several lines if there are several folders named "myDirectory".
    fi
    
  • Проверьте наличие одной или нескольких папок на основе шаблона в текущем каталоге:

    found=`find -maxdepth 1 -type d -name "my*"`
    if [ -n "$found"]
    then
        # The variable 'found' contains the full path where folders "my*" have been found.
    fi
    
  • Обе комбинации. В следующем примере он проверяет наличие папки в текущем каталоге:

    found=`find -maxdepth 1 -type d -name "myDirectory"`
    if [ -n "$found"]
    then
        # The variable 'found' is not empty => "myDirectory"` exists.
    fi
    
19
ответ дан 12 сент. '08 в 23:17
источник

Чтобы проверить несколько каталогов, используйте этот код:

if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
    # Things to do
fi
16
ответ дан 29 дек. '16 в 12:45
источник
  1. Простой скрипт для проверки наличия или отсутствия файла или файла:

    if [ -d /home/ram/dir ]   # for file "if [-f /home/rama/file]" 
    then 
        echo "dir present"
    else
        echo "dir not present"
    fi
    
  2. Простой скрипт для проверки наличия каталога или нет:

    mkdir tempdir   # if you want to check file use touch instead of mkdir
    ret=$?
    if [ "$ret" == "0" ]
    then
        echo "dir present"
    else
        echo "dir not present"
    fi
    

    Вышеприведенные скрипты будут проверять, присутствует ли каталог или нет.

    $? если последний успешный процесс возвращает значение "0" else, отличное от нуля. предположим, что tempdir уже присутствует, тогда mkdir tempdir даст ошибку, как mkdir tempdir ниже:

    mkdir: невозможно создать каталог tempdir: Файл существует

16
ответ дан 15 мая '18 в 8:36
источник

Вы считали, что просто делаете то, что хотите делать, if хотите, а не смотрите, прежде чем прыгать?

IE, если вы хотите проверить наличие каталога, прежде чем вводить его, попробуйте сделать это:

if pushd /path/you/want/to/enter; then
    # commands you want to run in this directory
    popd
fi

Если путь, который вы даете pushd существует, вы введете его, и он выйдет с 0, что означает, что then будет выполняться эта часть инструкции. Если он не существует, ничего не произойдет (кроме некоторого выхода, говорящего, что каталог не существует, что, вероятно, является полезным побочным эффектом в любом случае для отладки).

Кажется лучше, чем это, что требует повторения:

if [ -d /path/you/want/to/enter ]; then
    pushd /path/you/want/to/enter
    # commands you want to run in this directory
    popd
fi

То же самое работает с cd - mv rm then cd, mv, rm, и т.д... если вы попробуете их на файлы, которые не существуют, они будут выходить с ошибкой и распечатать сообщение о том, что не существует, и ваш, then блок будет пропускаются. Если вы попробуете их в существующих файлах, команда выполнит и завершит со статусом 0, что позволит выполнить then блок.

15
ответ дан 07 дек. '17 в 19:24
источник

Проверьте, существует ли каталог, иначе сделайте один

[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
14
ответ дан 23 марта '16 в 10:25
источник
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It a directory and not a symbolic link"

N.B: Котировочные переменные являются хорошей практикой.

14
ответ дан 19 апр. '15 в 3:54
источник
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
12
ответ дан 19 апр. '13 в 1:12
источник

Этот ответ завершен как оболочка script

Примеры

$ is_dir ~                           
YES

$ is_dir /tmp                        
YES

$ is_dir ~/bin                       
YES

$ mkdir '/tmp/test me'

$ is_dir '/tmp/test me'
YES

$ is_dir /asdf/asdf                  
NO

# Example of calling it in another script
DIR=~/mydata
if [ $(is_dir $DIR) == "NO" ]
then
  echo "Folder doesnt exist: $DIR";
  exit;
fi

is_dir

function show_help()
{
  IT=$(CAT <<EOF

  usage: DIR
  output: YES or NO, depending on whether or not the directory exists.

  )
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

DIR=$1
if [ -d $DIR ]; then 
   echo "YES";
   exit;
fi
echo "NO";
11
ответ дан 15 апр. '16 в 21:13
источник

Использование проверки -e будет проверять файлы, включая каталоги.

if [ -e ${FILE_PATH_AND_NAME} ]
then
    echo "The file or directory exists."
fi
9
ответ дан 25 июля '13 в 16:12
источник

По Jonathan комментарий:

Если вы хотите создать каталог, и он еще не существует, то самым простым методом является использование mkdir -p, который создает каталог - и любые отсутствующие каталоги до пути - и не прерывается, если каталог уже существует, поэтому вы можете сделать все сразу:

mkdir -p /some/directory/you/want/to/exist || exit 1
8
ответ дан 13 сент. '15 в 0:21
источник
if [ -d "$DIRECTORY" ]; then
    # Will enter here if $DIRECTORY exists
fi

Это не совсем так... Если вы хотите перейти в этот каталог, вам также необходимо иметь права на выполнение в каталоге. Возможно, вам также нужны права на запись.

Therfore:

if [ -d "$DIRECTORY" ] && [ -x "$DIRECTORY" ] ; then
    # ... to go to that directory (even if DIRECTORY is a link)
    cd $DIRECTORY
    pwd
fi

if [ -d "$DIRECTORY" ] && [ -w "$DIRECTORY" ] ; then
    # ... to go to that directory and write something there (even if DIRECTORY is a link)
    cd $DIRECTORY
    touch foobar
fi
7
ответ дан 18 марта '10 в 13:52
источник

Команда ls в сочетании с параметром -l (длинный список) возвращает атрибуты информации о файлах и каталогах.
В частности, первый символ вывода ls -l обычно равен d или - (тире). В случае d тот, который указан, является надежным каталогом.

Следующая команда только в одной строке сообщит вам, если указанная переменная ISDIR содержит путь к каталогу или нет:

[[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] &&
    echo "YES, $ISDIR is a directory." || 
    echo "Sorry, $ISDIR is not a directory"

Практическое использование:

    [claudio@nowhere ~]$ ISDIR="$HOME/Music" 
    [claudio@nowhere ~]$ ls -ld "$ISDIR"
    drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." ||
        echo "Sorry, $ISDIR is not a directory"
    YES, /home/claudio/Music is a directory.

    [claudio@nowhere ~]$ touch "empty file.txt"
    [claudio@nowhere ~]$ ISDIR="$HOME/empty file.txt" 
    [claudio@nowhere ~]$ [[ $(ls -ld "$ISDIR" | cut -c1) == 'd' ]] && 
        echo "YES, $ISDIR is a directory." || 
        echo "Sorry, $ISDIR is not a directoy"
    Sorry, /home/claudio/empty file.txt is not a directory
6
ответ дан 15 сент. '11 в 22:47
источник

(1)

[ -d Piyush_Drv1 ] && echo ""Exists"" || echo "Not Exists"

(2)

[ `find . -type d -name Piyush_Drv1 -print | wc -l` -eq 1 ] && echo Exists || echo "Not Exists"

(3)

[[ -d run_dir  && ! -L run_dir ]] && echo Exists || echo "Not Exists"

Если возникла проблема с одним из предложенных выше способов.

С командой ls; случаи, когда каталог не существует - отображается сообщение об ошибке

$[[ls -ld SAMPLE_DIR| grep ^d | wc -l -eq 1]] && & эхо существует || не существует -ksh: not: not found [Нет такого файла или каталога]

5
ответ дан 13 мая '15 в 10:21
источник

Если вы хотите проверить, существует ли каталог, независимо от того, является ли это реальной директорией или символической ссылкой, используйте это:

ls $DIR
if [ $? != 0 ]; then
        echo "Directory $DIR already exists!"
        exit 1;
fi
echo "Directory $DIR does not exist..."

Объяснение: Команда "ls" дает ошибку "ls:/x: Нет такого файла или каталога", если каталог или символическая ссылка не существует, а также устанавливает код возврата, который вы можете получить с помощью "$?"., до ненулевой (обычно "1" ). Обязательно проверьте код возврата непосредственно после вызова "ls".

5
ответ дан 07 янв. '14 в 20:59
источник
file="foo" 
if [[ -e "$file" ]]; then echo "File Exists"; fi;
5
ответ дан 22 февр. '13 в 5:39
источник

Отличные решения там, но в конечном итоге каждый script завершится неудачно, если вы не находитесь в правильном каталоге. Итак, код выглядит следующим образом:

if [ -d "$LINK_OR_DIR" ]; then 
if [ -L "$LINK_OR_DIR" ]; then
    # It is a symlink!
    # Symbolic link specific commands go here
    rm "$LINK_OR_DIR"
else
    # It a directory!
    # Directory command goes here
    rmdir "$LINK_OR_DIR"
fi
fi

будет успешно выполняться только в том случае, если на момент выполнения вы находитесь в каталоге, в котором есть подкаталог, который вы проверили.

Я понимаю начальный вопрос, например: проверить, существует ли каталог независимо от положения пользователя в файловой системе. Поэтому использование команды "найти" может сделать трюк:

dir=" "
echo "Input directory name to search for:"
read dir
find $HOME -name $dir -type d

Это решение хорошо, потому что оно позволяет использовать подстановочные знаки, полезную функцию при поиске файлов/каталогов. Единственная проблема заключается в том, что если искомый каталог не существует, команда "найти" ничего не выведет на stdout (не элегантное решение на мой вкус) и, тем не менее, будет иметь нулевой выход. Может быть, кто-то может улучшить это.

4
ответ дан 12 дек. '11 в 23:40
источник

Ниже можно использовать

find . -type d -name dirname -prune -print
4
ответ дан 13 авг. '14 в 16:41
источник
  • 1
  • 2

Другие вопросы по меткам или Задайте вопрос