Comprobando desde el script de shell si un directorio contiene archivos

116

Desde un script de shell, ¿cómo verifico si un directorio contiene archivos?

Algo parecido a esto

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

pero que funciona si el directorio contiene uno o varios archivos (el anterior solo funciona con exactamente 0 o 1 archivos).

ionn
fuente
Por lo que vale su ejemplo, el bien hace lo que quiere en ksh y zsh
Dave Webb
2
@DaveWebb No, no es así. Si el globo se expande a más de una palabra, la prueba zsh informa 'prueba: demasiados argumentos'.
Jens
"huzzah" significa "el directorio no está vacío".
funroll
Si el directorio contiene solo un subdirectorio vacío, ¿eso cuenta como "archivos que contienen"?
Keith Thompson
Relacionado: Encontrar directorios vacíos UNIX
Joseph Holsten

Respuestas:

72

Las soluciones hasta ahora utilizan ls. Aquí hay una solución de 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
fuente
8
siempre que recuerde volver a establecer las opciones a su valor original al final del guión :)
Jean
Esta es una versión ligeramente mejorada que se encarga de restablecer la configuración de 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 qué no utilizar un subnivel para restablecer la configuración:files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*)
TeamBob
7
@teambob si usa un sub-shell: files=$(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*) entonces la instrucción if debería cambiar if [ ${#files} -gt 0 ];o tal vez simplemente olvidó el () alrededor del comando del sub-shell? files=($(shopt -s nullglob;shopt -s dotglob;echo /some/dir/*))
stoutyhk
2
@stoutyhk $ (...) restaura la configuración, no se requiere una subcapa separada. El uso de $ (...) genera una nueva instancia del shell. El entorno de esta nueva instancia se desecha una vez finalizado el comando. Editar: Se encontró una referencia tldp.org/LDP/abs/html/commandsub.html "La sustitución de comandos invoca una subshell".
Teambob
140

Tres mejores trucos


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

Este truco es 100% bashe invoca (genera) un sub-shell. La idea es de Bruno De Fraine y mejorada por el comentario de 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: no hay diferencia entre un directorio vacío y uno que no existe (e incluso cuando la ruta proporcionada es un archivo).

Hay una alternativa similar y más detalles (y más ejemplos) en las preguntas frecuentes 'oficiales' para el 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 truco está inspirado en el artículo de nixCraft publicado en 2007. Agregar 2>/dev/nullpara suprimir el error de salida "No such file or directory".
Véase también la respuesta de Andrew Taylor (2008) y la respuesta 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

o la versión bashism de una línea:

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

Nota: ls regresa $?=2cuando el directorio no existe. Pero no hay diferencia entre un archivo y un directorio vacío.


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

Este último truco está inspirado en la respuesta de gravstar donde -maxdepth 0se reemplaza por -pruney mejorado por phils comentario 's.

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

una variación 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

Explicación:

  • find -prunees similar a find -maxdepth 0usar menos caracteres
  • find -empty imprime los directorios y archivos vacíos
  • find -type d imprime directorios solamente

Nota: También puede reemplazar [ -n "$(find your/dir -prune -empty)" ]solo por la versión abreviada a continuación:

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 en la mayoría de los casos, pero tenga en cuenta que las rutas maliciosas pueden expresar un comando ...

olibre
fuente
2
Creo que puede simplificar la opción de búsqueda [ -n "$(find "your/dir" -prune -empty)" ]para evitar la repetición de la ruta del directorio.
phils
Mientras lo usaba if [ ``ls -A your/dir`` ]en un script, llegué a la conclusión de que funciona bien para un directorio con 0, 1 o 2 subdirectorios, pero falla para un directorio con más de 2 subdirectorios. line 17: [: 20150424-002813: unary operator expecteddonde 20150424-002813estaba uno de los nombres de directorio. La cáscara usada fue /bin/bash/. Finalmente lo cambié als "$destination" | tail -1
Christophe De Troyer
Hola @ChristopheDeTroyer No puedo reproducir tu problema. Por mi lado if [ ``ls -A my/dir`` ]sale por error bash: [: -A: binary operator expected. Probado en las versiones de bash 4.1.2 y 4.2.53.
olibre
1
Bueno, me motivó principalmente a comentar debido a la inconsistencia percibida (ya que la -nvariante estaba en el título pero no en el párrafo siguiente). Entonces, sí, está bien.
maxschlepzig
1
Estoy usando su solución -n, todavía mi script todavía se queja de esto ls: cannot access '/path': No such file or directory. ¿Hay alguna forma de suprimir este mensaje? Me gustaría fallar silenciosamente allí.
Freedo
48

¿Qué tal lo siguiente?

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

De esta forma no es necesario generar una lista completa del contenido del directorio. El reades tanto descartar la salida como hacer que la expresión se evalúe como verdadera solo cuando se lee algo ( /some/dir/es decir, se encuentra vacío por find).

mweerden
fuente
3
o simplementefind /some/dir/ -maxdepth 0 -empty -exec echo "huzzah" \;
doubleDown
5
+1 Esta es la solución más elegante. No implica el análisis de la lssalida y no se basa en funciones de shell no predeterminadas.
7
Sin embargo, se basa en las primarias -maxdepthy no estándar -empty.
chepner
21

Tratar:

if [ ! -z `ls /some/dir/*` ]; then echo "huzzah"; fi
Greg Hewgill
fuente
Esto funcionó para mí, ¡pero no puedo formatear este maldito mensaje! <br> exportar tmp = /bin/ls <some_dir>/* 2> /dev/nullif [! -z "$ tmp"]; luego echo Something is there fi
AndrewStone
1
Para los idiotas de Bash como yo, si quieren comprobar lo contrario, que el directorio está vacío, utilice if [-z ls /some/dir/*]; luego repita "huzzah"; fi
Chris Moschini
4
Puede usar en -nlugar de ! -z(ambos son equivalentes, pero por qué no usar la forma más corta cuando existe).
n.
Con ZSH este ejemplo arroja un error, la idea es que no se arroje el error ... BigGray% if [ ! -z ls / some / dir / * `]; luego repita "huzzah"; fi zsh: no se encontraron coincidencias: / some / dir / * `
Hvisage
no funciona para mí sin comillas dobles ls...en 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
fuente
15

¡Tenga cuidado con los directorios con muchos archivos! Podría llevar algún tiempo evaluar el lscomando.

En mi opinión, la mejor solución es la que utiliza

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

¿Podrías comparar el resultado de esto?

 ls -A /some/dir | wc -l
DGM
fuente
4
# Comprueba si un directorio contiene archivos no ocultos.
#
# uso: si está vacío "$ HOME"; luego repita "Bienvenido a casa"; fi
#
esta vacio() {
    por _ief en $ 1 / *; hacer
        si [-e "$ _ief"]; luego
            volver 1
        fi
    hecho
    volver 0
}

Algunas notas de implementación:

  • El forbucle evita una llamada a un lsproceso externo . Todavía lee todas las entradas del directorio una vez. Esto solo se puede optimizar escribiendo un programa en C que use readdir () explícitamente.
  • El test -einterior del bucle captura el caso de un directorio vacío, en cuyo caso a la variable _iefse le asignaría el valor "somedir / *". Solo si ese archivo existe, la función devolverá "no vacío"
  • Esta función funcionará en todas las implementaciones POSIX. Pero tenga en cuenta que Solaris / bin / sh no entra en esa categoría. Su testimplementación no es compatible con la -ebandera.
Roland Illig
fuente
1
Esto ignoraría los archivos de puntos en el directorio si dotglobno se establece -shopt -s dotglob
l0b0
4

Esto me dice si el directorio está vacío o si no lo está, la cantidad de archivos que contiene.

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
fuente
¿Alguien puede explicarme por qué fui votado en contra? Si estoy escribiendo dados, me gustaría saber por qué;)
Daishi
1
No voté en contra de esto, pero supongo que es porque estás analizando la salida dels .
Toby Speight
¿El artículo vinculado no está claro? Si es así, envíe un correo electrónico al autor (no a mí).
Toby Speight
1
@TobySpeight Veo el punto. Pero en este caso, estoy contando las líneas, no enumerándolas. Debería dar un resultado falso solo si el nombre de un archivo contiene una nueva línea. Y si los nombres de los archivos contienen nuevas líneas, algo mucho más importante debe haberse jodido en alguna parte;)
Daishi
3

Esta puede ser una respuesta muy tardía, pero aquí hay una solución que funciona. ¡Esta línea solo reconoce la existencia de archivos! No le dará un falso positivo si existen directorios.

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

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

Suponga que usted no tiene un archivo llamado *en /any/dir/you/check, que debería funcionar en bash dash posh busybox shy zshpero (por zsh) requieren unsetopt nomatch.

Los rendimientos deben ser comparables a cualquiera lsque use *(glob), supongo que será lento en directorios con muchos nodos (mi /usr/bincon más de 3000 archivos no fue tan lento), usará al menos la memoria suficiente para asignar todos los directorios / nombres de archivo (y más) como todos se pasan (resuelven) a la función como argumentos, algunos shell probablemente tienen límites en el número de argumentos y / o la longitud de los argumentos.

Sería bueno tener una forma portátil rápida de O (1) cero recursos para verificar si un directorio está vacío.

actualizar

La versión anterior no tiene en cuenta los archivos / directorios ocultos, en caso de que se requieran más pruebas, como los trucos 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 )

Pero, en cambio, estoy pensando en algo como esto:

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

Alguna preocupación acerca de las diferencias de barras al final del argumento y la salida de búsqueda cuando el directorio está vacío, y las líneas nuevas al final (pero esto debería ser fácil de manejar), lamentablemente en mi busybox shprograma lo que probablemente sea un error en la find -> ddtubería con la salida truncada aleatoriamente ( si utilicé catla salida es siempre la misma, parece estar ddcon el argumento count).

Alex
fuente
Amo la solución portátil. Vine a dar la misma respuesta. Lo acababa de escribir de manera diferente (devuelva 2 si no es un directorio). Además, estas soluciones portátiles tienen la ventaja de no llamar a ningún programa externo, lo que podría contar como una ventaja para los sistemas restringidos o integrados. Solo me preocupa que el uso de "()" pueda crear un nuevo subproceso (o al menos obligar a copiar el entorno y esas cosas y luego volver a cambiar). Eche un vistazo a esto: is_empty () {_d = "$ {1: -.}"; [! -d "$ {_ d}"] && return 2; set - "$ {_ d}" / * "$ {_ d}" /.[!.]* "$ {_ d}" /..?*; ["$ { }" = "$ {_ d} / $ {_ d} /. [!.] * $ {_ d} /..?*"]; };
Diego Augusto Molina
@DiegoAugustoMolina Recientemente en un proyecto tuve que hacer esta prueba nuevamente, si un directorio estaba vacío, al principio usé python, luego como prácticamente instalé python solo para eso, implementé la prueba en c, la implementación es de un extremo banalidad, me pregunto por qué nunca se agregó como una prueba o como un comando independiente
Alex
1
Yo también necesitaba una solución recientemente a este problema para un sistema (realmente) limitado. Incluso optimicé un poco el código anterior para no usar ninguna variable adicional. Una sola línea hackish y fea, pero genial. Sírvase usted mismo:is_empty(){ [ ! -d "${1}" ] && return 2;set -- "${1}" "${1}"/* "${1}"/.[!.]* "${1}"/..?*;[ "${*}" = "${1} ${1}/* ${1}/.[!.]* ${1}/..?*" ]; };
Diego Augusto Molina
2

ZSH

Sé que la pregunta estaba marcada para bash; pero, solo como referencia, para usuarios de zsh :

Prueba de directorio no vacío

Para comprobar si foono está vacío:

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

donde, si foono está vacío, forse ejecutará el código del bloque.

Prueba de directorio vacío

Para comprobar si fooestá vacío:

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

donde, si fooestá vacío, forse ejecutará el código del bloque.

Notas

No necesitamos citar el directorio fooanterior, pero podemos hacerlo si es necesario:

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

También podemos probar más de un objeto, incluso si no es un directorio:

$ 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

Todo lo que no sea un directorio simplemente se ignorará.

Extras

Como estamos haciendo globbing, podemos usar cualquier glob (o expansión de llaves):

$ 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

También podemos examinar objetos que se colocan en una matriz. Con los directorios como arriba, por ejemplo:

$ 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

Por lo tanto, podemos probar objetos que ya pueden estar configurados en un parámetro de matriz.

Tenga en cuenta que for, obviamente, el código del bloque se ejecuta en todos los directorios. Si esto no es deseable, simplemente puede completar un parámetro de matriz y luego operar en ese parámetro:

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

Explicación

Para los usuarios de zsh existe el (F)calificador glob (ver man zshexpn), que coincide con directorios "llenos" (no vacíos):

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

El calificador (F)enumera los objetos que coinciden: es un directorio Y no está vacío. Entonces, (^F)coincide: no es un directorio O está vacío. Por lo tanto, (^F)solo también enumeraría archivos regulares, por ejemplo. Por lo tanto, como se explica en la zshexppágina del manual, también necesitamos el (/)calificador glob, que enumera solo directorios:

$ 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

Por lo tanto, para verificar si un directorio determinado está vacío, puede ejecutar:

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

y solo para estar seguro de que no se capturará un directorio que no esté vacío:

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

¡Ups! Dado Yque no está vacío, zsh no encuentra coincidencias para (/^F)("directorios que están vacíos") y por lo tanto escupe un mensaje de error que dice que no se encontraron coincidencias para el glob. Por lo tanto, debemos suprimir estos posibles mensajes de error con el (N)calificador glob:

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

Por lo tanto, para los directorios vacíos necesitamos el calificador (N/^F), que se puede leer como: "no me advierta sobre fallas, directorios que no están llenos".

De manera similar, para los directorios que no están vacíos necesitamos el calificador (NF), que también podemos leer como: "no me adviertan sobre fallas, directorios llenos".

Zorawar
fuente
1

Me sorprende que no se haya mencionado la guía de wooledge sobre directorios vacíos . Esta guía, y todo Wooledge realmente, es una lectura obligada para preguntas de tipo shell.

De nota de esa página:

Nunca intente analizar la salida de ls. Incluso las soluciones ls -A pueden romperse (por ejemplo, en HP-UX, si eres root, ls -A hace exactamente lo contrario de lo que hace si no eres root, y no, no puedo inventar algo tan increíble estúpido).

De hecho, es posible que desee evitar la pregunta directa por completo. Por lo general, la gente quiere saber si un directorio está vacío porque quieren hacer algo relacionado con los archivos que contiene, etc. Busque la pregunta más amplia. Por ejemplo, uno de estos ejemplos basados ​​en búsquedas puede ser una solución adecuada:

   # 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

Más comúnmente, todo lo que realmente se necesita es algo como esto:

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

En otras palabras, la persona que hace la pregunta puede haber pensado que se necesitaba una prueba explícita de directorio vacío para evitar un mensaje de error como mympgviewer: ./*.mpg: No existe tal archivo o directorio cuando en realidad no se requiere tal prueba.

obispo
fuente
1

Pequeña variación de la respuesta de Bruno :

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

Esto funciona para mi

loockass
fuente
1

Tomando una pista (o varias) de la respuesta de olibre, me gusta una función Bash:

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

Porque aunque crea una subcapa, es lo más parecido a una solución O (1) que puedo imaginar y darle un nombre lo hace legible. Entonces puedo escribir

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

En cuanto a O (1), hay casos atípicos: si un directorio grande ha tenido todas o todas las entradas eliminadas, excepto la última, es posible que "find" tenga que leer todo para determinar si está vacío. Creo que el rendimiento esperado es O (1) pero el peor de los casos es lineal en el tamaño del directorio. No he medido esto.

Para Dummies
fuente
0

Hasta ahora no he visto una respuesta que use grep, lo que creo que daría una respuesta más simple (¡sin demasiados símbolos extraños!). Así es como comprobaría si existe algún archivo en el directorio usando bourne shell:

esto devuelve el número de archivos en un directorio:

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

puede completar la ruta del directorio donde está escrito el directorio. La primera mitad de la tubería asegura que el primer carácter de salida sea "-" para cada archivo. egrep luego cuenta el número de líneas que comienzan con ese símbolo usando expresiones regulares. ahora todo lo que tiene que hacer es almacenar el número que obtiene y compararlo usando comillas inversas como:

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

x es una variable de su elección.

Neumático Jecht
fuente
0

Mezclando ciruelas y últimas respuestas, llegué a

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

que funciona para caminos con espacios también

Laurent G
fuente
0

Respuesta simple con bash :

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

Yo iría por find:

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

Esto verifica el resultado de buscar solo archivos en el directorio, sin pasar por los subdirectorios. Luego verifica la salida usando la -zopción tomada de man test:

   -z STRING
          the length of STRING is zero

Vea algunos resultados:

$ mkdir aaa
$ dir="aaa"

Directorio vacío:

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

Solo dirs en él:

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

Un archivo en el directorio:

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

Un archivo en un subdirectorio:

$ touch aaa/bbb/another_file
$ [ -z "$(find aaa/ -maxdepth 1 -type f)" ] && echo "empty"
empty
fedorqui 'Así que deja de hacer daño'
fuente
0

Con alguna solución, pude encontrar una forma sencilla de averiguar si hay archivos en un directorio. Esto se puede extender con más comandos grep para verificar específicamente archivos .xml o .txt, etc. Ej: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
fuente
-1
if ls /some/dir/* >/dev/null 2>&1 ; then echo "huzzah"; fi;
Toby
fuente
Me gusta este porque no hay comillas ni corchetes que crucen el comando.
Dave Webb
Tenga cuidado de no usar esto si lo establece nullglob, porque entonces el lscomando tendrá éxito.
Steve Kehlet
No funcionará en todos los entornos en caso de que el directorio tenga archivos dot.
Diego Augusto Molina
-1

para probar un directorio 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;
DAKOTA DEL NORTE
fuente
-1

Prueba con el comando find. Especifique el directorio codificado o como argumento. Luego inicie buscar para buscar todos los archivos dentro del directorio. Compruebe si el retorno de la búsqueda es nulo. Hacer eco de los datos 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
fuente
Si el directorio tiene directorios vacíos o archivos no regulares (sockets, dispositivos char, enlaces simbólicos, etc.) dentro, esto no funcionará. Se informará que el directorio está vacío.
Diego Augusto Molina
@DiegoAugustoMolina si entendí correctamente en la pregunta fue que estamos buscando verificar si los archivos existen (como archivos en literal) esa es la razón por la que se usó el argumento -f. pero sus comentarios siguen siendo ciertos.
igiannak
-2

No me gustan las ls - Asoluciones publicadas. Lo más probable es que desee probar si el directorio está vacío porque no desea eliminarlo. Lo siguiente hace eso. Sin embargo, si solo desea registrar un archivo vacío, seguramente eliminarlo y recrearlo es más rápido que enumerar archivos posiblemente infinitos.

Esto debería funcionar...

if !  rmdir ${target}
then
    echo "not empty"
else
    echo "empty"
    mkdir ${target}
fi
el camarero
fuente
4
Esto no funciona si el usuario no tiene permiso de escritura ${target}/...
Jens
Es una mala idea hacer que una prueba sea destructiva. Entre otras cosas, introduce condiciones de carrera.
4dummies
-2

Funciona bien para mí esto (cuando 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

Con verificación 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
fuente