Проверьте, существует ли каталог в оболочке script
Какую команду можно использовать для проверки наличия или отсутствия каталога в оболочке script?
Ответы
Ответ 1
Чтобы проверить, существует ли каталог в сценарии оболочки, вы можете использовать следующее:
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 в другом ответе.
Если переменные содержат пробелы или другие необычные символы, это может привести к сбою сценария.
Ответ 2
Не забудьте всегда переносить переменные в двойные кавычки, ссылаясь на них в
a bash script. Дети в эти дни растут с идеей, что они могут иметь пробелы и множество других забавных персонажей в своих именах каталогов. (Пространства! В мои дни у нас не было никаких фантастических пространств!))
Однажды один из этих детей запустит ваш script с $DIRECTORY
, установленным на "My M0viez"
, и ваш script взорвется. Вы этого не хотите. Поэтому используйте это.
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
Ответ 3
Обратите внимание, что тест -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 условных выражениях и [
встроенная команда и [[
составная комм..
Ответ 4
Я нахожу версию с двумя скобками test
делает естественные логические тесты написания:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It a bona-fide directory"
fi
Ответ 5
Более короткая форма:
[ -d "$DIR" ] && echo "Yes"
Ответ 6
Чтобы проверить, существует ли каталог, вы можете использовать простую структуру, например:
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
Ответ 7
-
Простой скрипт для проверки наличия или отсутствия файла или файла:
if [ -d /home/ram/dir ] # for file "if [-f /home/rama/file]"
then
echo "dir present"
else
echo "dir not present"
fi
-
Простой скрипт для проверки наличия каталога или нет:
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: Файл существует
Ответ 8
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
Ответ 9
Вы можете использовать test -d
(см. man test
).
-d file
Истина, если файл существует и является каталогом.
Например:
test -d "/etc" && echo Exists || echo Does not exist
Примечание. Команда test
такая же, как условное выражение [
(см. man [
), поэтому оно переносится по сценариям оболочки.
[
- Это синоним встроенного test
, но последний аргумент должен быть буквальным ]
, чтобы соответствовать открытию [
.
Для получения возможных вариантов или дополнительной помощи проверьте:
-
help [
-
help test
-
man test
или man [
Ответ 10
Или для чего-то совершенно бесполезного:
[ -d . ] || echo "No"
Ответ 11
Здесь очень прагматичная идиома:
(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
. На этом уровне я бы предпочел сохранить его простым - аргументы функции являются просто строками.
Ответ 12
if [ -d "$Directory" -a -w "$Directory" ]
then
#Statements
fi
Вышеприведенный код проверяет, существует ли каталог и доступен ли он.
Ответ 13
Введите этот код в bash promt
if [ -d "$DIRECTORY" ]; then
# if true this block of code will execute
fi
Ответ 14
Дополнительные функции с использованием 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
Ответ 15
Собственно, вы должны использовать несколько инструментов для получения пуленепробиваемого подхода:
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), выгода больше, чем проблема.
Ответ 16
Вы считали, что просто делаете то, что хотите делать, 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
блок.
Ответ 17
Чтобы проверить несколько каталогов, используйте этот код:
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
# Things to do
fi
Ответ 18
Проверьте, существует ли каталог, иначе сделайте один
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
Ответ 19
[[ -d "$DIR" && ! -L "$DIR" ]] && echo "It a directory and not a symbolic link"
N.B: Котировочные переменные являются хорошей практикой.
Ответ 20
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"
Ответ 21
Этот ответ завершен как оболочка 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";
Ответ 22
Использование проверки -e
будет проверять файлы, включая каталоги.
if [ -e ${FILE_PATH_AND_NAME} ]
then
echo "The file or directory exists."
fi
Ответ 23
По Jonathan комментарий:
Если вы хотите создать каталог, и он еще не существует, то самым простым методом является использование mkdir -p
, который создает каталог - и любые отсутствующие каталоги до пути - и не прерывается, если каталог уже существует, поэтому вы можете сделать все сразу:
mkdir -p /some/directory/you/want/to/exist || exit 1
Ответ 24
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
Ответ 25
Команда 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"
Практическое использование:
[[email protected] ~]$ ISDIR="$HOME/Music"
[[email protected] ~]$ ls -ld "$ISDIR"
drwxr-xr-x. 2 claudio claudio 4096 Aug 23 00:02 /home/claudio/Music
[[email protected] ~]$ [[ $(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.
[[email protected] ~]$ touch "empty file.txt"
[[email protected] ~]$ ISDIR="$HOME/empty file.txt"
[[email protected] ~]$ [[ $(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
Ответ 26
file="foo"
if [[ -e "$file" ]]; then echo "File Exists"; fi;
Ответ 27
Если вы хотите проверить, существует ли каталог, независимо от того, является ли это реальной директорией или символической ссылкой, используйте это:
ls $DIR
if [ $? != 0 ]; then
echo "Directory $DIR already exists!"
exit 1;
fi
echo "Directory $DIR does not exist..."
Объяснение: Команда "ls" дает ошибку "ls:/x: Нет такого файла или каталога", если каталог или символическая ссылка не существует, а также устанавливает код возврата, который вы можете получить с помощью "$?"., до ненулевой (обычно "1" ).
Обязательно проверьте код возврата непосредственно после вызова "ls".
Ответ 28
(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 [Нет такого файла или каталога]
Ответ 29
Как насчет file
программы. Учитывая, что все каталоги также являются файлами в linux, достаточно выполнить следующую команду:
file $directory_name
Проверка несуществующего файла: file blah
Выход: cannot open 'blah' (No such file or directory)
Проверка существующего каталога: file bluh
Выход: bluh: directory
Ответ 30
Отличные решения там, но в конечном итоге каждый 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 (не элегантное решение на мой вкус) и, тем не менее, будет иметь нулевой выход. Может быть, кто-то может улучшить это.