Я хочу проверить, не содержит ли каталог никаких файлов. Если так, я пропущу некоторую обработку.
Я попробовал следующее:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Это дает следующую ошибку:
line 1: [: too many arguments
Есть ли решение / альтернатива?
Ответы:
Также было бы здорово проверить, существует ли каталог раньше.
источник
&&
и||
одновременно! Еслиecho "Not Empty"
неecho "Empty"
получится, побежит! Попробуйecho "test" && false || echo "fail"
! Да, я знаю,echo
что не подведет, но если вы измените любую другую команду, вы будете удивлены![ "$(ls -A /)" ] && touch /non-empty || echo "Empty"
- если вы хотите «пометить» непустые каталоги созданным файлом с именемnon-empty
, произойдет сбой и будет напечатано «Пусто».touch /empty
в моей линии?if [ -n "$(ls -A /path/to/dir)" ]; then
... Пожалуйста, обновите ответ, прежде чем кто-то вставит этот код в свой сервер и хакер поймет, как его использовать. Если/path/to/dir
не пусто, то имена файлов там передаются как аргументы,/bin/test
которые явно не предназначены. Просто добавьте-n
аргумент, проблема решена. Спасибо!Нет необходимости считать что-либо или ракушки. Вы также можете использовать
read
в сочетании сfind
. Еслиfind
вывод пуст, вы вернетеfalse
:Это должно быть портативным.
источник
echo
звонки отражают неправильный результат: в моем тесте (под Cygwin)find . -mindepth 1 | read
было 141 код ошибки вread
возвращает 0, а для пустого - 1.set -o pipefail
источник
-n
на правильность и безопасность (проверка с каталогом с пробелами в имени, проверка с непустым каталогом с именем '0 = 1').... [ -n "$(find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty 2>/dev/null)" ]; ...
grep
. serverfault.com/questions/225798/…find "$DIR_TO_CHECK" -maxdepth 0 -type d -empty | grep .
, и полагаться на статус выхода из grep. Как бы вы это ни делали, это очень правильный ответ на этот вопрос.источник
Это сделает работу в текущем рабочем каталоге (.):
или та же команда разделена на три строки, чтобы быть более читабельной:
Просто замените
ls -1A . | wc -l
на,ls -1A <target-directory> | wc -l
если вам нужно запустить его в другой целевой папке.Edit : я заменил
-1a
с-1A
(см @Daniel комментарий)источник
ls -A
вместо Некоторые файловые системы не имеют.
и..
символических ссылок в соответствии с документами.-1
безусловно, излишним. Даже еслиls
не будет печатать один элемент в строке, когда он будет передан по конвейеру, это не повлияет на идею проверки, выдало ли оно ноль или более строк.Используйте следующее:
Таким образом, вы не зависите от формата вывода
ls
.-mindepth
пропускает сам каталог,-maxdepth
предотвращает рекурсивную защиту в подкаталогах для ускорения работы.источник
wc -l
иfind
формат вывода (который является достаточно простым , хотя).Используя массив:
источник
shopt -s nullglob
${#files[@]} == 2
Предположение не выдерживает для корневого каталога (вы, вероятно , не проверить , если он пустой , но некоторый код , который не знает о том , что ограничения могли бы).Хакерский, но бездарный, без PID способ:
Это использует тот факт, что
test
встроенная команда завершается с 2, если задано более одного аргумента после-e
: во-первых,"$1"/*
glob расширяется с помощью bash. Это приводит к одному аргументу на файл. ТакЕсли файлов нет, звездочка в
test -e "$1"*
не расширяется, поэтому Shell возвращается к попытке файла с именем*
, который возвращает 1.... за исключением случаев, когда на самом деле существует один файл с точным именем
*
, звездочка расширяется до нуля, звездочка, которая заканчивается тем же вызовом, что и выше, т.е.test -e "dir/*"
, только на этот раз возвращает 0. (Спасибо @TrueY за указание на это.)Если есть один файл,
test -e "dir/file"
запускается, который возвращает 0.Но если файлов больше, чем 1,
test -e "dir/file1" "dir/file2"
запускается, и bash сообщает об этом как об ошибке использования, то есть 2.case
оборачивает всю логику так, что только первый случай с 1 состоянием выхода считается успешным.Возможные проблемы, которые я не проверял:
Есть больше файлов, чем количество разрешенных аргументов - я думаю, это может вести себя подобно случаю с 2+ файлами.
Или на самом деле есть файл с пустым именем - я не уверен, что это возможно на любой вменяемой OS / FS.
источник
test -e dir/*
вызывается. Если в dir единственным файлом является '*', то test вернет 0. Если файлов больше, то он вернет 2. Таким образом, он работает как описано.С FIND (1) (в Linux и FreeBSD) вы можете нерекурсивно просматривать запись каталога с помощью "-maxdepth 0" и проверять, является ли она пустой с помощью "-empty". Применительно к вопросу это дает:
источник
Я думаю, что лучшее решение:
спасибо https://stackoverflow.com/a/91558/520567
Это анонимное редактирование моего ответа, которое может кому-то пригодиться или не пригодиться. Небольшое изменение дает количество файлов:
Это будет работать правильно, даже если имена файлов содержат пробелы.
источник
РЕДАКТИРОВАТЬ: Я думаю, что это решение отлично работает с GNU Find, после быстрого взгляда на реализацию . Но это может не работать, например, с поиском netbsd . Действительно, он использует поле st_size stat (2). Руководство описывает это как:
Лучшее решение, также более простое:
Кроме того, -прень в 1-м решении бесполезна.
РЕДАКТИРОВАТЬ: нет-выход для gnu find .. вышеуказанное решение хорошо для поиска NetBSD. Для GNU find это должно работать:
источник
-exit
предиката .Это все здорово - просто превратил его в скрипт, чтобы я мог проверять наличие пустых каталогов ниже текущего. Ниже следует поместить в файл с именем 'findempty', поместить в путь где-нибудь, чтобы bash мог найти его и затем запустить chmod 755. Я думаю, можно легко изменить ваши специфические потребности.
источник
Это работает для меня, чтобы проверить и обработать файлы в каталоге
../IN
, учитывая, что скрипт находится в../Script
каталоге:источник
Как насчет тестирования, если каталог существует и не пуст в одном операторе if?
источник
Для любого каталога, кроме текущего, вы можете проверить, является ли он пустым, попытавшись сделать
rmdir
это, потому чтоrmdir
гарантированно произойдет сбой для непустых каталогов. Если всеrmdir
получилось, и вы действительно хотели, чтобы пустой каталог выдержал тест, простоmkdir
снова.Не используйте этот хак, если есть другие процессы, которые могут стать некомпетентными из-за каталога, который, как они знают, ненадолго прекратит свое существование.
Если у
rmdir
вас не получится, и вы можете тестировать каталоги, которые могут содержать большое количество файлов, любое решение, основанное на глобализации оболочки, может работать медленно и / или работать с ограничениями длины командной строки. Вероятно, лучше использоватьfind
в этом случае. Самое быстроеfind
решение, которое я могу придумать, выглядит какЭто работает для версий GNU и BSD,
find
но не для версий Solaris, в которой отсутствует каждый из этихfind
операторов. Люблю свою работу, Оракул.источник
Вы можете попытаться удалить каталог и дождаться ошибки; rmdir не удалит каталог, если он не пуст.
источник
rmdir
потерпит неудачу, если у меня нет разрешения на удаление каталога; или если это Btrfs subvolume; или если он принадлежит файловой системе только для чтения. А еслиrmdir
неmkdir
выходит из строя и запускается: что, если уже удаленный каталог принадлежит другому пользователю? как насчет его (возможно, нестандартных) разрешений? ACL? расширенные атрибуты? Все потеряно.