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

Как проверить скрипт на наличие файлов в скрипте оболочки?

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

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

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

Ответы [ 25 ]

121 голосов
/ 28 июля 2013

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


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 для #bash IRC канала :

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

или версия однострочного bashism:

[[ $(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

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

61 голосов
/ 18 сентября 2008

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

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
48 голосов
/ 18 сентября 2008

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

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

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

19 голосов
/ 18 сентября 2008

Попробуйте:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
14 голосов
/ 24 января 2011
# 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
}
13 голосов
/ 18 сентября 2008

Берегите каталоги с большим количеством файлов! Для оценки команды ls может потребоваться некоторое время.

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

find /some/dir/ -maxdepth 0 -empty
9 голосов
/ 18 сентября 2008
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi
6 голосов
/ 18 сентября 2008

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

 ls -A /some/dir | wc -l
4 голосов
/ 08 марта 2010
# Checks whether a directory contains any nonhidden files.
#
# usage: if isempty "$HOME"; then echo "Welcome home"; fi
#
isempty() {
    for _ief in $1/*; do
        if [ -e "$_ief" ]; then
            return 1
        fi
    done
    return 0
}

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

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

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

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...