Какую команду можно использовать для проверки существования или отсутствия каталога в сценарии оболочки?
Чтобы проверить, существует ли каталог в сценарии оболочки, вы можете использовать следующее:
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
Однако, как отмечает Jon Ericson, последующие команды могут работать не так, как задумано, если вы не учтете, что символическая ссылка на каталог также пройдет эту проверку. Например, выполнив следующее:
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's a directory!
# Directory command goes here.
rmdir "$LINK_OR_DIR"
fi
fi
Обратите особое внимание на двойные кавычки, которыми обведены переменные, причина этого объясняется 8jean <a href="https://stackoverflow.com/a/67458/102401">- в другом ответе.
Если переменные содержат пробелы или другие необычные символы, это может привести к ошибке в работе скрипта.
Не забывайте всегда заключать переменные в двойные кавычки, когда ссылаетесь на них в сценарии bash. Дети в наши дни растут с идеей, что в именах каталогов можно использовать пробелы и множество других забавных символов. (Пробелы! В мои времена у нас не было причудливых пробелов! ;))
Однажды один из таких детей запустит ваш скрипт с $DIRECTORY
, установленным на "My M0viez"
, и ваш скрипт взорвется. Вы не хотите этого. Поэтому используйте это.
if [ -d "$DIRECTORY" ]; then
# Will enter here if $DIRECTORY exists, even if it contains spaces
fi
Обратите внимание, что тест -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 и [[
встроенной команде](https://www.gnu.org/software/bash/manual/bash.html#index-_005b) и [[[
составной команде](https://www.gnu.org/software/bash/manual/bash.html#index-_005b_005b).
Я нахожу двойной кронштейн версия "тест" позволяет писать тесты на логику более естественным:
if [[ -d "${DIRECTORY}" && ! -L "${DIRECTORY}" ]] ; then
echo "It's a bona-fide directory"
fi
Чтобы проверить, существует ли каталог, вы можете использовать простой, если структура такая:
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
если [ -д /дома/оперативная память/реж ] # для файл "если [-Ф /домашний/рама/файл] и" тогда Эхо "присутствует и quot реж; еще Эхо "реж нет и" интернет
команды mkdir tempdir # если вы хотите проверить файл используйте прикосновения вместо команды mkdir рэт=$? если [ " и$рет, что" == "в 0" и ] тогда Эхо "присутствует и quot реж; еще Эхо "реж нет и" интернет
Вышеуказанные скрипты будут проверять реж присутствует или нет
$ ?
, если последняя команда успешно возвращается на "0" и другое ненулевое значение.
tempdir предположим, `уже присутствует, то
функция mkdir tempdir` выдаст ошибку, как показано ниже:
команды mkdir: невозможно создать каталог ‘tempdir’: файл существует
if [ -d "$DIRECTORY" ]; then
# Here if $DIRECTORY exists
fi
Вы можете использовать тест -д "(см. " Тест человек`).
- д файл истина, если файл существует и является каталогом.
Например:
test -d "/etc" && echo Exists || echo Does not exist
Примечание: тест команда
такой же, как условное выражение [
(см.: человек
), так что's портативный через скрипты.
[
- это синоним длятеста
строение, но последний аргумент должен быть литералом]
, матч открытия[
.
Для возможных вариантов или дальнейшей помощи, проверьте:
тест
тест человек
или человек
Или за что-то абсолютно бесполезно:
[ -d . ] || echo "No"
Здесь's очень прагматические идиомы:
(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
}
Хорошая вещь об этом подходе заключается в том, что я не обязан думать о хорошем сообщении об ошибке.
кд
даст мне стандартное сообщение из одной строки уже поток stderr. Это также даст больше информации, чем я смогу обеспечить. Выполняя компакт
внутри подуровень ( ... )
, команда не изменяет текущий каталог вызывающего абонента. Если каталог существует, этот подуровень и функции просто нет.
Далее идет аргумент, что мы передаем компакт
: ${1:?путь ожидаемых}
. Это более сложная форма замещения параметр, который описан более подробно ниже.
Тл;др: если строка переданная в эту функцию пустой, мы снова выходим из подуровень ( ... )
и выходим из функции с заданным сообщением об ошибке.
Цитируя ksh93
Man-странице:
${parameter:?word}
если параметр установлен и не-null затем подставить его значение; в противном случае напечатать "слово" и выход из оболочки (если не интерактивные). если "слово" не указан, то стандартное сообщение печатается.
и
если двоеточие
:
опущен из приведенных выше выражений, то оболочки только проверяет, является ли параметр или нет.
Формулировка здесь свойственно документации оболочке, как "слово" может относиться для любого разумного строке, включая пробелы.
В данном конкретном случае, я знаю, что стандартное сообщение об ошибке 1: параметр не задан недостаточно, поэтому я увеличить на тип значения, что мы ожидаем здесь -
путь` каталога.
В philosphical Примечание:
Оболочка-это не объектно-ориентированный язык, поэтому в сообщении говорится, путь
, а не каталог
. На этом уровне, я'д, а держать его просто - аргументы функции являются просто строками.
if [ -d "$Directory" -a -w "$Directory" ]
then
#Statements
fi
Выше код проверяет, если каталог существует, если он является перезаписываемым.
find
Проверка существования папки в подкаталогах:
found=`find -type d -name "myDirectory"`.
if [ -n "$found"]
, то
# Переменная 'found' содержит полный путь, где находится "myDirectory".
# Она может содержать несколько строк, если существует несколько папок с именем "myDirectory".
fi
Проверка существования одной или нескольких папок по шаблону в текущем каталоге:
found=`find -maxdepth 1 -type d -name "my*"`.
if [ -n "$found"]
then
# Переменная 'found' содержит полный путь, по которому были найдены папки "my*".
fi
Обе комбинации. В следующем примере проверяется существование папки в текущем каталоге:
found=`find -maxdepth 1 -type d -name "myDirectory"`.
if [ -n "$found"]
then
# Переменная 'found' не пуста => "myDirectory"` существует.
fi
На самом деле, вы должны использовать несколько инструментов, чтобы получить пуленепробиваемый подход:
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's a dir";
fi
Нет необходимости беспокоиться о пробелы и специальные символы, как долго, как вы используете в "${}"
в.
Обратите внимание, что [[]]
не столь портативным, как []
, но поскольку большинство людей работает с современными версиями Баш (так ведь большинство людей не'т даже работать с командной строки :-P), то пользы больше, чем проблем.
Рассматривали ли вы просто делать то, что вы хотите сделать в "Если", а не осмотреться перед прыжком?
Т. е., если вы хотите проверить существование каталога, прежде чем войти в него, попробовать просто сделать это:
if pushd /path/you/want/to/enter; then
# commands you want to run in this directory
popd
fi
Если путь вы даете команды pushd
существует, вы'll вписывает его, и он'МР выходе с 0
, что означает то
часть инструкции будет выполнить. Если это не'т существуют, то ничего не произойдет (за исключением некоторых выходных говорю каталоге не'т существуют, что может быть полезным побочным эффектом в любом случае для отладки).
Кажется, лучше, чем это, которое требует повторяя себе:
if [ -d /path/you/want/to/enter ]; then
pushd /path/you/want/to/enter
# commands you want to run in this directory
popd
fi
То же самое работает с компакт
, МВ
, РМ
, и т. д.... Если вы попробовать их на файлов, что Дон'т существуют, они'МР выход с ошибкой и печатать сообщение, что он не'т существуют, и вашим", затем " блок будет пропущен. Если вы попробовать их на файлы, которые действительно существуют, то команда будет выполняться и выход со статусом 0
, позволяя вашим", затем " блок для выполнения.
Регистрация более чем одного использования каталога этот код:
if [ -d "$DIRECTORY1" ] && [ -d "$DIRECTORY2" ] then
# Things to do
fi
Проверить, если каталог существует, еще сделать один
[ -d "$DIRECTORY" ] || mkdir $DIRECTORY
[ -d ~/Desktop/TEMPORAL/ ] && echo "DIRECTORY EXISTS" || echo "DIRECTORY DOES NOT EXIST"