Verificar no script de shell se um diretório contém arquivos

116

Em um script de shell, como verifico se um diretório contém arquivos?

Algo parecido com isso

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

mas que funciona se o diretório contém um ou vários arquivos (o acima só funciona com exatamente 0 ou 1 arquivo).

ionn
fonte
Se valer a pena, seu exemplo good faz o que você quer em ksh e zsh
Dave Webb
2
@DaveWebb Não, não importa. Se o glob se expandir para mais de uma palavra, o teste zsh reporta 'teste: muitos argumentos'.
Jens,
"huzzah" significa "o diretório não está vazio".
funroll de
Se o diretório contém apenas um subdiretório vazio, isso conta como "contendo arquivos"?
Keith Thompson
Relacionado: Encontrando diretórios vazios UNIX
Joseph Holsten

Respostas:

72

As soluções até agora usam ls. Esta é uma solução totalmente bash:

#!/bin/bash
shopt -s nullglob dotglob     # To include hidden files
files=(/some/dir/*)
if [ ${#files[@]} -gt 0 ]; then echo "huzzah"; fi
Bruno De Fraine
fonte
8
contanto que você se lembre de definir as opções de volta aos seus valores originais no final do script :)
Jean,
Esta é uma versão ligeiramente melhorada que se encarrega de redefinir as configurações do 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
Por que não usar um subshell para redefinir as configurações:files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
teambob
7
@teambob se estiver usando um sub-shell: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) então a instrução if deve mudar para if [ ${#files} -gt 0 ];ou talvez você apenas tenha esquecido o () ao redor do comando do sub-shell? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk
2
@stoutyhk $ (...) restaura as configurações, nenhum subshell separado é necessário. Usando $ (...) gera uma nova instância do shell. O ambiente desta nova instância é descartado assim que o comando é concluído. Editar: Encontrada uma referência tldp.org/LDP/abs/html/commandsub.html "A substituição de comando invoca um subshell."
teambob
139

Três melhores truques


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

Este truque é 100% bashe invoca (gera) um sub-shell. A ideia é de Bruno De Fraine e melhorada pelo comentário do 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

Nota: não há diferença entre um diretório vazio e um não existente (e mesmo quando o caminho fornecido é um arquivo).

Há uma alternativa semelhante e mais detalhes (e mais exemplos) no FAQ 'oficial' do canal de 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)" ]

Este truque é inspirado no artigo da nixCraft postado em 2007. Adicione 2>/dev/nullpara suprimir o erro de saída "No such file or directory".
Veja também a resposta de Andrew Taylor (2008) e a resposta de 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

ou a versão do bashismo de uma linha:

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

Nota: ls retorna $?=2quando o diretório não existe. Mas não há diferença entre um arquivo e um diretório vazio.


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

Este último truque é inspirado na resposta da gravstar, onde -maxdepth 0é substituído -prunee melhorado pelo comentário de 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

uma variação usando -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

Explicação:

  • find -prune é semelhante a find -maxdepth 0 usar menos caracteres
  • find -empty imprime os diretórios e arquivos vazios
  • find -type d imprime diretórios apenas

Observação: você também pode substituir [ -n "$(find your/dir -prune -empty)" ]apenas pela versão abreviada abaixo:

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

Este último código funciona na maioria dos casos, mas esteja ciente de que caminhos maliciosos podem expressar um comando ...

Olibre
fonte
2
Acho que você pode simplificar a opção de localização [ -n "$(find "your/dir" -prune -empty)" ], para evitar a repetição do caminho do diretório.
phils
Ao usar if [ ``ls -A your/dir`` ]em um script, cheguei à conclusão de que funciona bem para um diretório com 0, 1 ou 2 subdiretórios, mas falha para um diretório com mais de 2 subdiretórios. line 17: [: 20150424-002813: unary operator expectedonde 20150424-002813estava um dos nomes de diretório. A concha usada era /bin/bash/. Eu finalmente mudei parals "$destination" | tail -1
Christophe De Troyer
Olá @ChristopheDeTroyer, não consigo reproduzir o seu problema. Do meu lado if [ ``ls -A my/dir`` ]sai por engano bash: [: -A: binary operator expected. Testado nas versões 4.1.2 e 4.2.53 do bash.
olibre
1
Bem, eu estava motivado principalmente para comentar por causa da inconsistência percebida (uma vez que a -nvariante estava no título, mas não no parágrafo abaixo). Então, sim, está bem.
maxschlepzig
1
Estou usando sua solução -n, mas meu script ainda reclama disso ls: cannot access '/path': No such file or directory. Existe uma maneira de suprimir esta mensagem? Eu gostaria de falhar silenciosamente lá.
Freedo
48

Que tal o seguinte:

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

Desta forma, não há necessidade de gerar uma listagem completa do conteúdo do diretório. O readserve para descartar a saída e fazer com que a expressão seja avaliada como verdadeira apenas quando algo for lido (ou seja, /some/dir/for encontrado vazio por find).

Mweerden
fonte
3
ou simplesmentefind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
doubleDown
5
+1 Esta é a solução mais elegante. Não envolve análise de lssaída e não depende de recursos de shell não padrão.
7
No entanto, depende do não padrão -maxdepthe dos -emptyprimários.
chepner de
21

Experimentar:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
Greg Hewgill
fonte
Isso funcionou para mim, mas não consigo formatar essa mensagem d * mn !!! <br> export tmp = /bin/ls <some_dir>/* 2> /dev/nullif [! -z "$ tmp"]; então echo Something is there fi
AndrewStone
1
Para idiotas do Bash como eu, se você quiser verificar o oposto - se o diretório está vazio - use if [-z ls /some/dir/*]; então echo "huzzah"; fi
Chris Moschini
4
Você pode usar em -nvez de ! -z(ambos são equivalentes, mas por que não usar a forma mais curta quando existe).
2014
Com ZSH este exemplo lança um erro, a ideia é não ter o erro lançado ... BigGray% if [ ! -z ls / some / dir / * `]; então echo "huzzah"; fi zsh: nenhuma correspondência encontrada: / some / dir / * `
Hvisage
não funciona para mim sem aspas duplas ls...em 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
fonte
15

Cuidado com os diretórios com muitos arquivos! Pode levar algum tempo para avaliar o lscomando.

IMO a melhor solução é aquela que usa

find /some/dir/ -maxdepth 0 -empty
Gravstar
fonte
8
DIR="/some/dir"
if [ "$(ls -A $DIR)" ]; then
     echo 'There is something alive in here'
fi
Andrew Taylor
fonte
6

Você poderia comparar a saída disso?

 ls -A /some/dir | wc -l
DGM
fonte
4
# Verifica se um diretório contém arquivos não ocultos.
#
# uso: if isempty "$ HOME"; em seguida, echo "Bem-vindo ao lar"; fi
#
está vazia() {
    para _ief em $ 1 / *; Faz
        if [-e "$ _ief"]; então
            retorno 1
        fi
    feito
    retornar 0
}

Algumas notas de implementação:

  • O forloop evita uma chamada para um lsprocesso externo . Ele ainda lê todas as entradas do diretório uma vez. Isso só pode ser otimizado escrevendo um programa C que usa readdir () explicitamente.
  • O test -edentro do loop captura o caso de um diretório vazio, caso em que a variável _iefseria atribuída ao valor "somedir / *". Somente se o arquivo existir a função retornará "não vazio"
  • Esta função funcionará em todas as implementações POSIX. Mas esteja ciente de que o Solaris / bin / sh não se enquadra nessa categoria. Sua testimplementação não suporta a -ebandeira.
Roland Illig
fonte
1
Isso iria ignorar dotfiles no diretório se dotglobnão for definido -shopt -s dotglob
10b0
4

Isso me diz se o diretório está vazio ou não, o número de arquivos que ele contém.

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
Daishi
fonte
Alguém pode me explicar por que fui rejeitado? Se estou escrevendo dados, gostaria de saber por quê;)
Daishi
1
Eu não votei contra isso, mas acho que é porque você está analisando a saída dels .
Toby Speight
o artigo vinculado não está claro? Se sim, envie um email para o autor (não para mim).
Toby Speight
1
@TobySpeight Eu entendo o ponto. Mas, neste caso, estou contando as linhas, não as enumerando. Deve dar um resultado falso apenas se o nome do arquivo contiver uma nova linha. E se os nomes dos arquivos contêm novas linhas, algo muito mais importante deve ter estragado em algum lugar;)
Daishi
3

Esta pode ser uma resposta muito tardia, mas aqui está uma solução que funciona. Esta linha reconhece apenas a existência de arquivos! Ele não fornecerá um falso positivo se houver diretórios.

if find /path/to/check/* -maxdepth 0 -type f | read
  then echo "Files Exist"
fi
Steven Penny
fonte
2
dir_is_empty() {
   [ "${1##*/}" = "*" ]
}

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

Suponha que você não tenha um arquivo nomeado *em /any/dir/you/check, ele deve funcionar bash dash posh busybox she, zshmas (para zsh) exigir unsetopt nomatch.

Os desempenhos devem ser comparáveis ​​a qualquer um lsque use *(glob), acho que será lento em diretórios com muitos nós (meu/usr/bin com mais de 3000 arquivos não foi tão lento), usará pelo menos memória suficiente para alocar todos os diretórios / nomes de arquivos (e mais) como todos eles são passados ​​(resolvidos) para a função como argumentos, alguns shell provavelmente têm limites no número de argumentos e / ou comprimento dos argumentos.

Seria bom ter uma maneira rápida e portátil O (1) de zero recursos para verificar se um diretório está vazio.

atualizar

A versão acima não leva em conta arquivos / diretórios ocultos, caso seja necessário mais algum teste, como os truques sh (shell POSIX)is_empty de Rich :

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

Mas, em vez disso, estou pensando em algo assim:

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

Alguma preocupação sobre as diferenças de barras finais do argumento e da saída de encontrar quando o dir está vazio, e novas linhas finais (mas isso deve ser fácil de manusear), infelizmente no meu busybox shprograma o que provavelmente é um bug no find -> ddtubo com a saída truncada aleatoriamente ( se usei cata saída é sempre a mesma, parece ser ddcom o argumento count).

Alex
fonte
Eu amo a solução portátil. Vim dar a mesma resposta. Eu tinha acabado de escrever de forma diferente (retorne 2 se não for um diretório). Além disso, essas soluções portáteis têm a vantagem de não chamar nenhum programa externo, o que pode contar como uma vantagem para sistemas restritos ou incorporados. Estou apenas preocupado que o uso de "()" possa criar um novo subprocesso (ou pelo menos forçar a cópia do ambiente e outras coisas e depois voltar). Dê uma olhada nisso: is_empty () {_d = "$ {1: -.}"; [! -d "$ {_ d}"] && return 2; set - "$ {_ d}" / * "$ {_ d}" /.[!.]* "$ {_ d}" /..?*; ["$ { }" = "$ {_ d} / $ {_ d} /. [!.] * $ {_ d} /..?*"]; };
Diego Augusto Molina
@DiegoAugustoMolina Recentemente em um projeto eu tive que fazer esse teste novamente, se um diretório estava vazio, no começo usei o python, então como praticamente instalei o python só para isso, implementei o teste em c, a implementação é extrema banalidade, eu me pergunto por que ele nunca foi adicionado como um teste ou como um comando autônomo
Alex
1
Eu também tenho precisado de uma solução recentemente para este problema para um sistema (realmente) restrito. Até otimizei um pouco o código anterior para não usar nenhuma variável extra. Uma linha simples e feia, mas ótima. Sirva-se:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
Diego Augusto Molina
2

ZSH

Eu sei que a pergunta foi marcada para bash; mas, apenas para referência, para usuários zsh :

Teste para diretório não vazio

Para verificar se foonão está vazio:

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

onde, se foonão estiver vazio, o código do forbloco será executado.

Teste para diretório vazio

Para verificar se fooestá vazio:

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

onde, se fooestiver vazio, o código do forbloco será executado.

Notas

Não precisamos citar o diretório fooacima, mas podemos fazer isso se precisarmos:

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

Também podemos testar mais de um objeto, mesmo que não seja um diretório:

$ 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

Tudo o que não for um diretório será simplesmente ignorado.

Extras

Já que estamos globbing, podemos usar qualquer glob (ou expansão de chave):

$ 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

Também podemos examinar objetos colocados em uma matriz. Com os diretórios acima, por exemplo:

$ 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

Assim, podemos testar objetos que já podem estar configurados em um parâmetro de matriz.

Observe que o código no forbloco é, obviamente, executado em cada diretório por vez. Se isso não for desejável, você pode simplesmente preencher um parâmetro de matriz e, em seguida, operar nesse parâmetro:

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

Explicação

Para usuários zsh, há o (F)qualificador glob (consulte Recursos man zshexpn), que corresponde a diretórios "completos" (não vazios):

$ 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/

O qualificador (F)lista os objetos que correspondem: é um diretório E não está vazio. Portanto, (^F)corresponde a: não é um diretório OU está vazio. Assim, (^F)sozinho também listaria arquivos regulares, por exemplo. Portanto, conforme explicado na zshexppágina do manual, também precisamos do (/)qualificador glob, que lista apenas os diretórios:

$ 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

Assim, para verificar se um determinado diretório está vazio, você pode executar:

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

e apenas para ter certeza de que um diretório não vazio não seria capturado:

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

Ops! Como Ynão está vazio, zsh não encontra correspondências para (/^F)("diretórios que estão vazios") e, portanto, exibe uma mensagem de erro informando que nenhuma correspondência para o glob foi encontrada. Portanto, precisamos suprimir essas possíveis mensagens de erro com o (N)qualificador glob:

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

Assim, para diretórios vazios, precisamos do qualificador (N/^F), que pode ser lido como: "não me avise sobre falhas, diretórios que não estão cheios".

Da mesma forma, para diretórios não vazios, precisamos do qualificador (NF), que também podemos ler como: "não me avise sobre falhas, diretórios completos".

Zorawar
fonte
1

Estou surpreso que o guia complicado sobre diretórios vazios não tenha sido mencionado. Este guia, e realmente tudo de lã, é uma leitura obrigatória para perguntas do tipo shell.

Digno de nota nessa página:

Nunca tente analisar a saída ls. Mesmo as soluções ls -A podem falhar (por exemplo, no HP-UX, se você for root, ls -A faz exatamente o oposto do que faria se você não fosse root - e não, não posso inventar algo tão incrivelmente estúpido).

Na verdade, pode-se desejar evitar a pergunta direta completamente. Normalmente as pessoas querem saber se um diretório está vazio porque querem fazer algo envolvendo os arquivos nele, etc. Observe a questão maior. Por exemplo, um desses exemplos baseados em localização pode ser uma solução apropriada:

   # 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

Mais comumente, tudo o que é realmente necessário é algo assim:

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

Em outras palavras, a pessoa que fez a pergunta pode ter pensado que um teste explícito de diretório vazio era necessário para evitar uma mensagem de erro como mympgviewer: ./*.mpg: Não existe esse arquivo ou diretório quando na verdade esse teste não é necessário.

bispo
fonte
1

Pequena variação da resposta de Bruno :

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

Funciona para mim

loockass
fonte
1

Pegando uma dica (ou várias) da resposta de olibre, gosto de uma função Bash:

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

Porque, embora crie um subshell, é o mais próximo de uma solução O (1) que posso imaginar e dar um nome a torna legível. Eu posso então escrever

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

Quanto a O (1), há casos atípicos: se um diretório grande teve todos ou todos, exceto a última entrada excluída, "find" pode ter que ler tudo para determinar se está vazio. Eu acredito que o desempenho esperado é O (1), mas o pior caso é linear no tamanho do diretório. Eu não medi isso.

Para Leigos
fonte
0

Até agora não vi uma resposta que use grep, o que acho que daria uma resposta mais simples (sem muitos símbolos estranhos!) Aqui está como eu verificaria se existem arquivos no diretório usando o shell do bourne:

isso retorna o número de arquivos em um diretório:

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

você pode preencher o caminho do diretório onde o diretório está escrito. A primeira metade do pipe garante que o primeiro caractere de saída seja "-" para cada arquivo. egrep então conta o número de linhas que começam com aquele símbolo usando expressões regulares. agora tudo o que você precisa fazer é armazenar o número obtido e compará-lo usando crases como:

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

x é uma variável de sua escolha.

Jecht Tire
fonte
0

Misturando coisas de poda e últimas respostas, eu tenho que

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

que funciona para caminhos com espaços também

Laurent G
fonte
0

Resposta simples com bash :

if [[ $(ls /some/dir/) ]]; then echo "huzzah"; fi;
Thomas Steinbach
fonte
0

Eu iria para find:

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

Isso verifica a saída de procurar apenas arquivos no diretório, sem passar pelos subdiretórios. Em seguida, verifica a saída usando a -zopção retirada de man test:

   -z STRING
          the length of STRING is zero

Veja alguns resultados:

$ mkdir aaa
$ dir="aaa"

Dir vazio:

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

Apenas dirs nele:

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

Um arquivo no diretório:

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

Um arquivo em um subdiretório:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
fedorqui 'então pare de prejudicar'
fonte
0

Com alguma solução alternativa, poderia encontrar uma maneira simples de descobrir se há arquivos em um diretório. Isso pode ser estendido com mais comandos grep para verificar especificamente arquivos .xml ou .txt, etc. Ex: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
fonte
-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
Toby
fonte
Eu gosto deste porque não há aspas ou colchetes obstruindo o comando.
Dave Webb
Cuidado para não usar isso se você definir nullglob, porque o lscomando será bem-sucedido.
Steve Kehlet
Não funcionará em todos os ambientes caso o diretório tenha arquivos dot.
Diego Augusto Molina
-1

para testar um diretório de destino específico

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;
ND
fonte
-1

Tente com o comando find. Especifique o diretório codificado ou como argumento. Em seguida, inicie a localização para pesquisar todos os arquivos dentro do diretório. Verifique se o retorno do find é nulo. Ecoar os dados de encontrar

#!/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
igiannak
fonte
Se o diretório tiver diretórios vazios ou arquivos não regulares (sockets, dispositivos char, links simbólicos, etc.) dentro, isso não funcionará. O diretório seria relatado como vazio.
Diego Augusto Molina
@DiegoAugustoMolina se eu entendi corretamente a questão é que estamos procurando verificar se existem arquivos (como arquivos em literal) esse é o motivo pelo qual o argumento -f foi usado. mas seus comentários ainda são verdadeiros.
igiannak
-2

Não gosto das ls - Asoluções postadas. Provavelmente, você deseja testar se o diretório está vazio porque não deseja excluí-lo. O seguinte faz isso. Se, no entanto, você deseja apenas registrar um arquivo vazio, certamente excluí-lo e recriá-lo é mais rápido do que listar arquivos possivelmente infinitos.

Isso deve funcionar ...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi
o jartender
fonte
4
Isso não funciona se o usuário não tiver permissão de gravação para ${target}/...
Jens
Apenas uma má ideia fazer um teste destrutivo. Entre outras coisas, apresenta condições de corrida.
4dummies
-2

Funciona bem para mim (quando existe dir):

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

Com verificação completa:

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
fonte