Проверка из сценария оболочки, содержит ли каталог файлы

117

Как из сценария оболочки проверить, есть ли в каталоге файлы?

Что-то похожее на это

if [ -e /some/dir/* ]; then echo "huzzah"; fi;

но это работает, если каталог содержит один или несколько файлов (указанный выше работает только с 0 или 1 файлом).

ionn
источник
Для чего стоит ваш пример, хороший делает то, что вы хотите, в ksh и zsh
Дэйв Уэбб
2
@DaveWebb Нет, это не так. Если глобус расширяется до более чем одного слова, тест zsh сообщает «тест: слишком много аргументов».
Jens
«ура» означает «каталог не пустой».
funroll 07
Если каталог содержит только пустой подкаталог, считается ли это «содержащим файлы»?
Кейт Томпсон
Связанный: Поиск пустых каталогов UNIX
Джозеф Холстен

Ответы:

72

Решения, которые до сих пор используют ls . Вот решение для всех bash:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
Бруно де Фрайн
источник
8
при условии, что вы не забудете установить для параметров их исходное значение в конце сценария :)
Жан,
Это немного улучшенная версия, которая заботится о сбросе настроек bash:shopt -q nullglob || resetnullglob=1; shopt -s nullglob; shopt -q dotglob || resetdotglob=1; shopt -s dotglob; files=(/some/dir/*); [ "$files" ] && echo "wowzers"; [ "$resetdotglob" ] && shopt -u dotglob; [ "$resetnullglob" ] && shopt -u nullglob;
user123444555621,
12
Почему бы не использовать подоболочку для сброса настроек:files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
teambob
7
@teambob при использовании вспомогательной оболочки: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) тогда оператор if должен измениться на if [ ${#files} -gt 0 ];или, может быть, вы просто забыли () вокруг команды вспомогательной оболочки? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk 04
2
@stoutyhk $ (...) восстанавливает настройки, отдельная подоболочка не требуется. Использование $ (...) порождает новый экземпляр оболочки. Окружение этого нового экземпляра отбрасывается после завершения команды. Изменить: нашел ссылку tldp.org/LDP/abs/html/commandsub.html «Подстановка команд вызывает подоболочку».
teambob
140

Три лучших трюка


shopt -s nullglob dotglob; f=your/dir/*; ((${#f}))

Этот трюк 100% bashи вызывает (порождает) суб-оболочку. Идея принадлежит Bruno De Fraine и улучшена комментарием teambob .

files=$(shopt -s nullglob dotglob; echo your/dir/*)
if (( ${#files} ))
then
  echo "contains files"
else 
  echo "empty (or does not exist or is a file)"
fi

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

В «официальном» FAQ для IRC-канала #bash есть похожая альтернатива и более подробная информация (и другие примеры) :

if (shopt -s nullglob dotglob; f=(*); ((${#f[@]})))
then
  echo "contains files"
else 
  echo "empty (or does not exist, or is a file)"
fi

[ -n "$(ls -A your/dir)" ]

Этот трюк основан на статье nixCraft, опубликованной в 2007 году. Добавьте, 2>/dev/nullчтобы подавить ошибку вывода "No such file or directory".
См. Также ответ Эндрю Тейлора (2008 г.) и ответ gr8can8dian (2011 г.).

if [ -n "$(ls -A your/dir 2>/dev/null)" ]
then
  echo "contains files (or is a file)"
else
  echo "empty (or does not exist)"
fi

или однострочная версия башизма:

[[ $(ls -A your/dir) ]] && echo "contains files" || echo "empty"

Примечание: ls возвращается, $?=2когда каталог не существует. Но никакой разницы между файлом и пустым каталогом.


[ -n "$(find your/dir -prune -empty)" ]

Этот последний трюк основан на ответе gravstar, где -maxdepth 0он заменен -pruneи улучшен комментарием phils .

if [ -n "$(find your/dir -prune -empty 2>/dev/null)" ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

вариант с использованием -type d:

if [ -n "$(find your/dir -prune -empty -type d 2>/dev/null)" ]
then
  echo "empty directory"
else
  echo "contains files (or does not exist or is not a directory)"
fi

Объяснение:

  • find -prune похож на чем find -maxdepth 0 использованию меньшего количества символов
  • find -empty печатает пустые каталоги и файлы
  • find -type d печатает только каталоги

Примечание: вы также можете заменить [ -n "$(find your/dir -prune -empty)" ]только сокращенной версией ниже:

if [ `find your/dir -prune -empty 2>/dev/null` ]
then
  echo "empty (directory or file)"
else
  echo "contains files (or does not exist)"
fi

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

olibre
источник
2
Я думаю, вы можете упростить опцию поиска [ -n "$(find "your/dir" -prune -empty)" ], чтобы избежать повторения пути к каталогу.
phils
При использовании if [ ``ls -A your/dir`` ]в сценарии я пришел к выводу, что он отлично работает для каталога с 0, 1 или 2 подкаталогами, но не работает для каталога с более чем 2 подкаталогами. line 17: [: 20150424-002813: unary operator expectedгде 20150424-002813было одно из имен каталогов. Используемый снаряд был /bin/bash/. Я наконец поменял его наls "$destination" | tail -1
Christophe De Troyer
Привет, @ChristopheDeTroyer, я не могу воспроизвести вашу проблему. На моей стороне if [ ``ls -A my/dir`` ]выходит по ошибке bash: [: -A: binary operator expected. Проверено на bash версий 4.1.2 и 4.2.53.
olibre
1
Что ж, я был в основном мотивирован для комментариев из-за кажущейся несогласованности (поскольку -nвариант был в заголовке, а затем не в нижеследующем абзаце). Так что да, все в порядке.
maxschlepzig 01
1
Я использую ваше решение -n, ​​но мой скрипт все еще жалуется на это ls: cannot access '/path': No such file or directory. Есть ли способ подавить это сообщение? Я бы хотел там молча потерпеть неудачу.
Freedo
48

Как насчет следующего:

if find /some/dir/ -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

Таким образом, нет необходимости создавать полный список содержимого каталога. Это readодновременно и отбрасывает вывод, и делает выражение истинным только тогда, когда что-то читается (т. /some/dir/Е. Обнаруживается пустым find).

Mweerden
источник
3
или простоfind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
doubleDown
5
+1 Это самое элегантное решение. Он не требует синтаксического анализа lsвывода и не полагается на функции оболочки, отличные от стандартных.
7
Однако он полагается на нестандартные -maxdepthи -emptyпервичные цвета.
chepner
21

Пытаться:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
Грег Хьюгилл
источник
У меня это сработало, но я не могу отформатировать это чертово сообщение !!! <br> экспорт tmp = /bin/ls <some_dir>/* 2> /dev/nullif [! -z "$ tmp"]; then echo Something is there fi
AndrewStone
1
Для таких идиотов Bash, как я, если вы хотите проверить обратное - что каталог пуст - просто используйте if [-z ls /some/dir/*]; затем эхо "ура"; fi
Крис Москини
4
Вы можете использовать -nвместо ! -z(они оба эквивалентны, но почему бы не использовать более короткую форму, если она существует).
n.st
С ZSH этот пример выдает ошибку, идея состоит в том, чтобы не выдавать ошибку ... BigGray% if [ ! -z ls / some / dir / * `]; затем эхо "ура"; fi zsh: совпадений не найдено: / some / dir / * `
Hvisage
у меня не работает без двойных кавычек ls...в bash
letmutx
15
# Works on hidden files, directories and regular files
### isEmpty()
# This function takes one parameter:
# $1 is the directory to check
# Echoes "huzzah" if the directory has files
function isEmpty(){
  if [ "$(ls -A $1)" ]; then
    echo "huzzah"
  else 
    echo "has no files"
  fi
}
gr8can8dian
источник
15

Позаботьтесь о каталогах с большим количеством файлов! Чтобы оценитьls .

ИМО лучшее решение - это то, которое использует

find /some/dir/ -maxdepth 0 -empty
Gravstar
источник
8
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi
Эндрю Тейлор
источник
6

Не могли бы вы сравнить результат этого?

 ls -A /some/dir | wc -l
DGM
источник
4
# Проверяет, содержит ли каталог какие-либо не скрытые файлы.
#
# использование: если пусто "$ HOME"; затем эхо «Добро пожаловать домой»; фи
#
пусто() {
    для _ief в $ 1 / *; делать
        если [-e "$ _ief"]; затем
            возврат 1
        фи
    сделано
    возврат 0
}

Некоторые примечания по реализации:

  • forЦикл избегает вызов внешнего lsпроцесса. Он по-прежнему считывает все записи каталога один раз. Это можно оптимизировать, только написав программу на C, которая явно использует readdir ().
  • test -eВнутри цикла ловит случай пустой каталог, в этом случае переменная _iefбудет присвоено значение «somedir / *». Только если этот файл существует, функция вернет "непустой"
  • Эта функция будет работать во всех реализациях POSIX. Но имейте в виду, что Solaris / bin / sh не попадает в эту категорию. Его testреализация не поддерживает -eфлаг.
Роланд Иллиг
источник
1
Это будет игнорировать точечные файлы в каталоге, если dotglobне установлено -shopt -s dotglob
l0b0
4

Это говорит мне, пуст ли каталог или нет, количество файлов, которые он содержит.

directory="/some/dir"
number_of_files=$(ls -A $directory | wc -l)

if [ "$number_of_files" == "0" ]; then
    echo "directory $directory is empty"
else
    echo "directory $directory contains $number_of_files files"
fi
Дайси
источник
Может ли кто-нибудь объяснить мне, почему я проиграл? Если я пишу дерьмо, я бы хотел знать, почему;)
Дайши
1
Я не отрицал это, но предполагаю, что это потому, что вы анализируете выводls .
Тоби Спейт
Связанная статья неясна? Если да, напишите автору (не мне).
Тоби Спейт
1
@TobySpeight Я вижу суть. Но в этом случае я считаю строки, не перечисляя их. Он должен давать ложный результат только в том случае, если имя файла содержит новую строку. И если имена файлов содержат новые строки, должно быть, где-то испортилось что-то гораздо более важное;)
Дайши
3

Это может быть очень поздний ответ, но вот решение, которое работает. Эта строка распознает только наличие файлов! Это не даст вам ложного срабатывания, если каталоги существуют.

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi
Стивен Пенни
источник
2
dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

if dir_is_empty /some/dir/* ; then
   echo "huzzah"
fi

Предположим , у вас нет файла с именем *в /any/dir/you/check, он должен работать на bash dash posh busybox shи zshа (для Zsh) требуется unsetopt nomatch.

Характеристики должны быть сопоставимы с теми, lsкоторые используют *(glob), я думаю, будет медленным в каталогах с большим количеством узлов (мой /usr/binс более чем 3000 файлами пошел не так медленно), будет использовать по крайней мере достаточно памяти, чтобы выделить все каталоги / имена файлов (и многое другое) поскольку все они передаются (разрешаются) в функцию в качестве аргументов, некоторые оболочки, вероятно, имеют ограничения на количество аргументов и / или длину аргументов.

Было бы неплохо иметь переносимый быстрый способ с нулевыми ресурсами O (1), чтобы проверить, пуст ли каталог.

Обновить

Версия выше , не учитывает скрытые файлы / директории, в случае , если требуются еще несколько испытаний, как is_emptyот ш Рича (POSIX оболочки) уловки :

is_empty () (
cd "$1"
set -- .[!.]* ; test -f "$1" && return 1
set -- ..?* ; test -f "$1" && return 1
set -- * ; test -f "$1" && return 1
return 0 )

Но вместо этого я думаю о чем-то вроде этого:

dir_is_empty() {
    [ "$(find "$1" -name "?*" | dd bs=$((${#1}+3)) count=1 2>/dev/null)" = "$1" ]
}

Некоторая озабоченность по поводу отличий конечных косых черт от аргумента и вывода find, когда каталог пуст, и конечных символов новой строки (но с этим должно быть легко справиться), к сожалению, на моем busybox shшоу, что, вероятно, является ошибкой на find -> ddконвейере с выводом, усеченным случайным образом ( если я использовал, catто вывод всегда один и тот же, вроде бы ddс аргументом count).

Alex
источник
Мне нравится портативное решение. Я пришел дать такой же ответ. Я только что написал по-другому (верните 2, если не каталог). Кроме того, эти переносимые решения имеют то преимущество, что они не вызывают никаких внешних программ, что может считаться плюсом для ограниченных или встроенных систем. Меня беспокоит только то, что использование «()» может создать новый подпроцесс (или, по крайней мере, заставить скопировать среду и прочее, а затем переключиться обратно). Взгляните на это: is_empty () {_d = "$ {1: -.}"; [! -d "$ {_ d}"] && return 2; set - "$ {_ d}" / * "$ {_ d}" /.[!.pting* "$ {_ d}" /..?*; ["$ { }" = "$ {_ d} / $ {_ d} /. [!.] * $ {_ d} /..?*"]; };
Диего Аугусто Молина
@DiegoAugustoMolina Недавно в проекте мне пришлось снова провести этот тест, если каталог был пуст, вначале я использовал python, затем, поскольку я практически установил python только для этого, я реализовал тест на c, реализация экстремальная банальность, интересно, почему его не добавили ни в качестве теста, ни как
Alex
1
Мне тоже недавно понадобилось решение этой проблемы для (действительно) ограниченной системы. Я даже немного оптимизировал предыдущий код, чтобы вообще не использовать никаких дополнительных переменных. Хакерский и некрасивый однострочный, но отличный. Служите себе:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
Диего Аугусто Молина
2

ЗШ

Я знаю, что вопрос был помечен как bash; но, для справки, для пользователей zsh :

Проверить наличие непустого каталога

Чтобы проверить, fooне пусто ли:

$ for i in foo(NF) ; do ... ; done

где, если fooне пусто, будет выполнен код в forблоке.

Проверить наличие пустого каталога

Чтобы проверить, fooпусто ли:

$ for i in foo(N/^F) ; do ... ; done

где, если fooпусто, будет выполнен код в forблоке.

Ноты

Нам не нужно было цитировать каталог fooвыше, но мы можем сделать это, если нам нужно:

$ for i in 'some directory!'(NF) ; do ... ; done

Мы также можем протестировать более одного объекта, даже если это не каталог:

$ mkdir X     # empty directory
$ touch f     # regular file
$ for i in X(N/^F) f(N/^F) ; do echo $i ; done  # echo empty directories
X

Все, что не является каталогом, просто игнорируется.

Дополнительно

Поскольку мы используем глобус, мы можем использовать любой глобус (или расширение скобок):

$ mkdir X X1 X2 Y Y1 Y2 Z
$ touch Xf                    # create regular file
$ touch X1/f                  # directory X1 is not empty
$ touch Y1/.f                 # directory Y1 is not empty
$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ for i in {X,Y}*(N/^F); do printf "$i "; done; echo  # print empty directories
X X2 Y Y2

Мы также можем исследовать объекты, помещенные в массив. С каталогами, как указано выше, например:

$ ls -F                       # list all objects
X/ X1/ X2/ Xf Y/ Y1/ Y2/ Z/
$ arr=(*)                     # place objects into array "arr"
$ for i in ${^arr}(N/^F); do printf "$i "; done; echo
X X2 Y Y2 Z

Таким образом, мы можем тестировать объекты, которые, возможно, уже были установлены в параметре массива.

Обратите внимание, что код в forблоке, очевидно, выполняется по очереди в каждом каталоге. Если это нежелательно, вы можете просто заполнить параметр массива, а затем работать с этим параметром:

$ for i in *(NF) ; do full_directories+=($i) ; done
$ do_something $full_directories

объяснение

Для пользователей zsh существует (F)квалификатор glob (см. man zshexpn), Который соответствует "полным" (непустым) каталогам:

$ mkdir X Y
$ touch Y/.f        # Y is now not empty
$ touch f           # create a regular file
$ ls -dF *          # list everything in the current directory
f X/ Y/
$ ls -dF *(F)       # will list only "full" directories
Y/

Квалификатор (F)перечисляет объекты, которые соответствуют: - это каталог И не является пустым. Итак, (^F)совпадения: не каталог ИЛИ пуст. Таким образом, в (^F)одиночку также будут перечислены, например, обычные файлы. Таким образом, как объясняется на zshexpстранице руководства , нам также нужен (/)квалификатор glob, который перечисляет только каталоги:

$ mkdir X Y Z
$ touch X/f Y/.f    # directories X and Y now not empty
$ for i in *(/^F) ; do echo $i ; done
Z

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

$ mkdir X
$ for i in X(/^F) ; do echo $i ; done ; echo "finished"
X
finished

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

$ mkdir Y
$ touch Y/.f
$ for i in Y(/^F) ; do echo $i ; done ; echo "finished"
zsh: no matches found: Y(/^F)
finished

К сожалению! Поскольку Yне пусто, zsh не находит совпадений для (/^F)(«пустые каталоги») и, таким образом, выдает сообщение об ошибке, говорящее, что совпадений для глобуса не найдено. Поэтому нам необходимо подавить эти возможные сообщения об ошибках с помощью (N)квалификатора glob:

$ mkdir Y
$ touch Y/.f
$ for i in Y(N/^F) ; do echo $i ; done ; echo "finished"
finished

Таким образом, для пустых каталогов нам нужен квалификатор (N/^F), который можно читать как «не предупреждать меня о сбоях, каталогах, которые не заполнены».

Точно так же для непустых каталогов нам нужен квалификатор (NF), который мы можем также читать как: «не предупреждать меня о сбоях, полные каталоги».

Зоравар
источник
1

Я удивлен, что руководство wooledge по пустым каталогам не упомянуто. Это руководство, как и вся информация о wooledge, является обязательным к прочтению при ответе на вопросы о типах оболочки.

Примечания с этой страницы:

Никогда не пытайтесь анализировать вывод ls. Даже решения ls -A могут сломаться (например, в HP-UX, если вы root, ls -A делает полную противоположность тому, что делает, если вы не root - и нет, я не могу придумать что-то настолько невероятное тупой).

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

   # Bourne
   find "$somedir" -type f -exec echo Found unexpected file {} \;
   find "$somedir" -maxdepth 0 -empty -exec echo {} is empty. \;  # GNU/BSD
   find "$somedir" -type d -empty -exec cp /my/configfile {} \;   # GNU/BSD

Чаще всего все, что действительно нужно, это что-то вроде этого:

   # Bourne
   for f in ./*.mpg; do
        test -f "$f" || continue
        mympgviewer "$f"
    done

Другими словами, человек, задающий вопрос, мог подумать, что явный тест пустого каталога необходим, чтобы избежать сообщения об ошибке, например mympgviewer: ./*.mpg: Нет такого файла или каталога, хотя на самом деле такой тест не требуется.

епископ
источник
1

Небольшой вариант ответа Бруно :

files=$(ls -1 /some/dir| wc -l)
if [ $files -gt 0 ] 
then
    echo "Contains files"
else
    echo "Empty"
fi

Меня устраивает

бездельник
источник
1

Взяв подсказку (или несколько) из ответа olibre, мне нравится функция Bash:

function isEmptyDir {
  [ -d $1 -a -n "$( find $1 -prune -empty 2>/dev/null )" ]
}

Потому что, хотя он создает одну подоболочку, он настолько близок к решению O (1), насколько я могу себе представить, а присвоение ему имени делает его читабельным. Тогда я могу написать

if isEmptyDir somedir
then
  echo somedir is an empty directory
else
  echo somedir does not exist, is not a dir, is unreadable, or is  not empty
fi

Что касается O (1), то здесь есть исключения: если из большого каталога были удалены все или все, кроме последней записи, «find», возможно, придется прочитать все это целиком, чтобы определить, пуст ли он. Я считаю, что ожидаемая производительность - O (1), но в худшем случае она линейна по размеру каталога. Я этого не измерял.

Для чайников
источник
0

До сих пор я не видел ответа с использованием grep, который, я думаю, дал бы более простой ответ (не слишком много странных символов!). Вот как я могу проверить, существуют ли какие-либо файлы в каталоге, используя оболочку bourne:

это возвращает количество файлов в каталоге:

ls -l <directory> | egrep -c "^-"

вы можете указать путь к каталогу, в который записан каталог. Первая половина вертикальной черты гарантирует, что первым символом вывода будет «-» для каждого файла. Затем egrep подсчитывает количество строк, начинающихся с этого символа, используя регулярные выражения. теперь все, что вам нужно сделать, это сохранить полученное число и сравнить его, используя обратные кавычки, например:

 #!/bin/sh 
 fileNum=`ls -l <directory> | egrep -c "^-"`  
 if [ $fileNum == x ] 
 then  
 #do what you want to do
 fi

x - это переменная по вашему выбору.

Jecht Tire
источник
0

Смешивая чернослив и последние ответы, я должен

find "$some_dir" -prune -empty -type d | read && echo empty || echo "not empty"

это работает и для путей с пробелами

Лоран Джи
источник
0

Простой ответ с помощью bash :

if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;
Томас Штайнбах
источник
0

Я бы пошел на find:

if [ -z "$(find $dir -maxdepth 1 -type f)" ]; then
    echo "$dir has NO files"
else
    echo "$dir has files"

Это проверяет результат поиска только файлов в каталоге, не просматривая подкаталоги. Затем он проверяет вывод, используя -zпараметр, взятый из man test:

   -z STRING
          the length of STRING is zero

Посмотрите некоторые результаты:

$ mkdir aaa
$ dir="aaa"

Пустой каталог:

$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Просто в нем режиссеры:

$ mkdir aaa/bbb
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty

Файл в каталоге:

$ touch aaa/myfile
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
$ rm aaa/myfile 

Файл в подкаталоге:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
fedorqui 'ТАК, хватит вредить'
источник
0

С помощью некоторого обходного пути я мог найти простой способ узнать, есть ли файлы в каталоге. Это может быть расширено с помощью команд grep для проверки конкретных файлов .xml или .txt и т. Д. Пример:ls /some/dir | grep xml | wc -l | grep -w "0"

#!/bin/bash
if ([ $(ls /some/dir | wc -l  | grep -w "0") ])
    then
        echo 'No files'
    else
        echo 'Found files'
fi
chanaka777
источник
-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
Тоби
источник
Мне это нравится, потому что в команде нет кавычек или скобок.
Дэйв Уэбб,
Будьте осторожны, чтобы не использовать это, если вы установили nullglob, потому что тогда lsкоманда будет успешной.
Стив Кехлет,
Не будет работать во всех средах, если в каталоге есть точечные файлы.
Диего Аугусто Молина
-1

для тестирования определенного целевого каталога

if [ -d $target_dir ]; then
    ls_contents=$(ls -1 $target_dir | xargs); 
    if [ ! -z "$ls_contents" -a "$ls_contents" != "" ]; then
        echo "is not empty";
    else
        echo "is empty";
    fi;
else
    echo "directory does not exist";
fi;
Северная Дакота
источник
-1

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

#!/bin/bash

_DIR="/home/user/test/"
#_DIR=$1
_FIND=$(find $_DIR -type f )
if [ -n "$_FIND" ]
then
   echo -e "$_DIR contains files or subdirs with files \n\n "
   echo "$_FIND"
else
echo "empty (or does not exist)"
fi
игианнак
источник
Если в каталоге есть пустые каталоги или нестандартные файлы (сокеты, символьные устройства, символические ссылки и т. Д.), Это не сработает. Будет сообщено, что каталог пуст.
Диего Аугусто Молина
@DiegoAugustoMolina, если я правильно понял, в вопросе было то, что мы хотим проверить, существуют ли файлы (как файлы в буквальном смысле), поэтому был использован аргумент причина -f. но ваши комментарии по-прежнему верны.
igiannak
-2

Мне не нравится ls - A решения. Скорее всего, вы хотите проверить, пуст ли каталог, потому что вы не хотите его удалять. Следующее делает это. Однако, если вы просто хотите зарегистрировать пустой файл, конечно, его удаление и воссоздание будет быстрее, чем перечисление, возможно, бесконечных файлов?

Это должно работать ...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi
thejartender
источник
4
Это не работает, если у пользователя нет разрешения на запись в ${target}/...
Jens
Просто плохая идея делать тест разрушительным. Среди прочего, он вводит условия гонки.
4dummies
-2

Для меня это хорошо работает (когда существует каталог):

some_dir="/some/dir with whitespace & other characters/"
if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; fi

При полной проверке:

if [ -d "$some_dir" ]; then
  if find "`echo "$some_dir"`" -maxdepth 0 -empty | read v; then echo "Empty dir"; else "Dir is NOT empty" fi
fi
Jerzyjerzy
источник