Quiero probar si un directorio no contiene ningún archivo. Si es así, omitiré algún procesamiento.
Intenté lo siguiente:
if [ ./* == "./*" ]; then
echo "No new file"
exit 1
fi
Eso da el siguiente error:
line 1: [: too many arguments
¿Hay una solución / alternativa?
Respuestas:
Además, sería genial verificar si el directorio existe antes.
fuente
&&
y al||
mismo tiempo! Siecho "Not Empty"
falla,echo "Empty"
correrá! Trateecho "test" && false || echo "fail"
! Sí, séecho
que no fallará, pero si cambia cualquier otro comando, ¡se sorprenderá![ "$(ls -A /)" ] && touch /non-empty || echo "Empty"
- si desea "marcar" los directorios no vacíos con un archivo creado llamadonon-empty
, fallará e imprimirá "Vacío".touch /empty
mi línea?if [ -n "$(ls -A /path/to/dir)" ]; then
... Actualice la respuesta antes de que alguien pegue este código en su servidor en algún lugar y un hacker descubra cómo explotarlo. Si/path/to/dir
no está vacío, los nombres de archivo se pasan como argumentos a los/bin/test
que claramente no se pretende. Simplemente agregue el-n
argumento, problema resuelto. ¡Gracias!No es necesario contar nada ni globos de concha. También se puede usar
read
en combinación confind
. Sifind
la salida está vacía, devolveráfalse
:Esto debería ser portátil.
fuente
echo
llamadas reflejan el resultado incorrecto: en mi prueba (bajo Cygwin)find . -mindepth 1 | read
tenía un código de error 141 en un directorio no vacío y 0 en un directorio vacíoread
devuelve 0, y para uno vacío, 1.set -o pipefail
fuente
-n
para ser correcta y segura (prueba con directorio con espacios en el nombre, prueba con directorio no vacío con nombre '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 .
y confiar en el estado de salida de grep. De cualquier forma que lo haga, esta es la respuesta correcta a esta pregunta.fuente
Esto hará el trabajo en el directorio de trabajo actual (.):
o el mismo comando dividido en tres líneas solo para ser más legible:
Simplemente reemplácelo
ls -1A . | wc -l
conls -1A <target-directory> | wc -l
si necesita ejecutarlo en una carpeta de destino diferente.Editar : lo reemplacé
-1a
con-1A
(vea el comentario de @Daniel)fuente
ls -A
en su lugar. Algunos sistemas de archivos no tienen.
y..
los enlaces simbólicos de acuerdo a la documentación.-1
Es definitivamente redundante. Incluso sils
no imprime un elemento por línea cuando se canalizará, no afectará la idea de verificar si produjo cero o más líneas.Use lo siguiente:
De esta manera, eres independiente del formato de salida de
ls
.-mindepth
omite el directorio en sí,-maxdepth
evita la defensa recursiva en subdirectorios para acelerar las cosas.fuente
wc -l
yfind
formato de salida (que es razonablemente sencillo sin embargo).Usando una matriz:
fuente
shopt -s nullglob
${#files[@]} == 2
suposición no representa el directorio raíz (probablemente no probará si está vacío, pero podría haber algún código que no conozca esa limitación).Una manera hacky, pero bash-only, sin PID:
Esto aprovecha el hecho de que el
test
builtin sale con 2 si se le da más de un argumento después-e
: Primero,"$1"/*
bash expande glob. Esto da como resultado un argumento por archivo. EntoncesSi no hay archivos, el asterisco
test -e "$1"*
no se expande, por lo que Shell recurre al archivo de prueba llamado*
, que devuelve 1.... excepto si realmente hay un archivo llamado exactamente
*
, entonces el asterisco se expande bien, asterisco, que termina como la misma llamada que antes, es decir.test -e "dir/*"
, solo que esta vez devuelve 0. (Gracias @TrueY por señalar esto).Si hay un archivo,
test -e "dir/file"
se ejecuta, que devuelve 0.Pero si hay más archivos que 1,
test -e "dir/file1" "dir/file2"
se ejecuta, que bash lo informa como un error de uso, es decir, 2.case
envuelve toda la lógica para que solo el primer caso, con 1 estado de salida, sea reportado como exitoso.Posibles problemas que no he verificado:
Hay más archivos que número de argumentos permitidos. Supongo que esto podría comportarse de manera similar al caso con 2+ archivos.
O en realidad hay un archivo con un nombre vacío: no estoy seguro de que sea posible en cualquier sistema operativo / FS sano.
fuente
test -e dir/*
se llama. Si el único archivo es '*' en el directorio, entonces la prueba devolverá 0. Si hay más archivos, entonces devuelve 2. Entonces funciona como se describe.Con FIND (1) (bajo Linux y FreeBSD) puede mirar de forma no recursiva una entrada de directorio a través de "-maxdepth 0" y probar si está vacía con "-empty". Aplicado a la pregunta esto da:
fuente
Creo que la mejor solución es:
gracias a https://stackoverflow.com/a/91558/520567
Esta es una edición anónima de mi respuesta que puede o no ser útil para alguien: una ligera alteración da la cantidad de archivos:
Esto funcionará correctamente incluso si los nombres de archivo contienen espacios.
fuente
EDITAR: Creo que esta solución funciona bien con gnu find, después de un rápido vistazo a la implementación . Pero esto puede no funcionar con, por ejemplo, el hallazgo de netbsd . De hecho, ese usa el campo st_size de stat (2). El manual lo describe como:
Una mejor solución, también más simple, es:
Además, la -prune en la primera solución es inútil.
EDITAR: no -exit para gnu find ... la solución anterior es buena para el hallazgo de NetBSD. Para GNU find, esto debería funcionar:
fuente
-exit
predicado .Todo esto es excelente, solo lo convertí en un script para que pueda verificar si hay directorios vacíos debajo del actual. Lo siguiente debe colocarse en un archivo llamado 'findempty', ubicado en la ruta en algún lugar para que bash pueda encontrarlo y luego ejecutar chmod 755. Supongo que puede modificarse fácilmente a sus necesidades específicas.
fuente
Esto funciona para mí, para verificar y procesar archivos en el directorio
../IN
, considerando que el script está en el../Script
directorio:fuente
¿Qué pasa con la prueba si el directorio existe y no está vacío en una declaración if?
fuente
Para cualquier directorio que no sea el actual, puede verificar si está vacío al intentarlo
rmdir
, porquermdir
se garantiza que fallará en los directorios no vacíos. Sirmdir
tiene éxito, y realmente quería que el directorio vacío sobreviviera a la prueba, solomkdir
vuelva a hacerlo.No utilices este truco si hay otros procesos que podrían descomponerse por un directorio que conocen sobre dejar brevemente de existir.
Si
rmdir
no funciona para usted, y podría estar probando directorios que podrían contener una gran cantidad de archivos, cualquier solución que se base en el bloqueo de shell podría volverse lenta y / o encontrarse con límites de longitud de línea de comando. Probablemente mejor usarfind
en ese caso. Lafind
solución más rápida que se me ocurre va comoEsto funciona para las versiones GNU y BSD,
find
pero no para Solaris, a la que le faltan todos estosfind
operadores. Amo tu trabajo, Oracle.fuente
Puede intentar eliminar el directorio y esperar un error; rmdir no eliminará el directorio si no está vacío.
fuente
rmdir
fallará si no tengo permiso para eliminar el directorio; o si es un subvolumen Btrfs; o si pertenece a un sistema de archivos de solo lectura. Y sirmdir
no falla y semkdir
ejecuta: ¿qué pasa si el directorio ya eliminado pertenecía a otro usuario? ¿Qué pasa con sus permisos (posiblemente no estándar)? ACL? atributos extendidos? Todo perdido