
Tengo un problema en un sistema operativo Linux que ejecuta una versión de SMB donde si la ruta absoluta a un directorio dentro de una carpeta compartida esmayor que 1024 bytes y el componente de nombre de archivo es mayor que 256 bytesel servicio SMB falla y bloquea todos los demás servicios para el acceso a la red, como SSH y FTP, silenciando la máquina.
Para evitar que el sistema falle, moví temporalmente un grupo de carpetas donde creo que la ruta del problema puede estar ubicada fuera de la Carpeta compartida. Necesito encontrar el archivo y la ruta del archivo que excedió esta limitación y cambiarles el nombre o eliminarlos, lo que me permitirá devolver la mayor parte de los archivos a la carpeta compartida.
he probado elencontrarygrepórdenes sin éxito. ¿Existe una cadena de comandos o secuencias de comandos que pueda utilizar para buscar los archivos y directorios infractores?
Por favor avise.
Respuesta1
Está escrito en Bash y utiliza funciones específicas (pero hay funciones similares disponibles en otros shells). Está diseñado para ejecutarse desde un directorio principal común a todos los archivos y directorios que le interesan. Tiene en cuenta la longitud de la ruta desde /
allí y la suma a la longitud de cada ruta evaluada. Si no quieres hacer eso, simplemente usa lenpwd=0
en lugar de lenpwd=${#PWD}
. Funcionará si hay archivos con espacios en sus nombres pero no aquellos que tienen nuevas líneas (que deberían eliminarse de cualquier manera). Imprime las longitudes y especificaciones de archivo de cualquier cosa que encuentre que cumpla con los criterios.
lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done
Respuesta2
No sé si te entendí bien, pero primero intenta:
for f in $( find /srv/smb -type f )
do
fname=$( basename "$f" )
pname=$( dirname "$f" )
l_fname=$( echo "$fname" | wc -c )
l_pname=$( echo "$pname" | wc -c )
if [ $l_fname -gt 256 ] ; then
# do somthing with $f when filename > 256b
rm -- "$f"
continue
fi
if [ $l_pname -gt 1024 ] ; then
# do something if path > 1024
echo "$f much too long!"
fi
done
Esto es solo un script que-no-lo-probé-pero-debería-funcionar-en-bash-an-equlas-shell. Siéntase libre de agregar verificación de errores y otras cosas útiles...
Respuesta3
Aquí hay una línea que genera la longitud del nombre del directorio, luego la longitud del nombre base, luego el nombre del directorio y, por último, el nombre base (para la posteridad). Acabo de usar el directorio de trabajo actual, pero esto se puede cambiar. Esto también se puede ampliar para extraer valores mayores que los dados.
find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
| awk '( NR%2 != 0){printf("%s ",$0);next}1 '
| awk '{print length($1)" "length($2)" "$1$2}'
Actualizar:
Para ordenar por longitud del nombre del directorio, agregue esto al final:
| sort -nr
Para ordenar por longitud del nombre base, agregue esto al final:
| sort -nr -k2
Actualización 2:
Según el comentario del autor, esto cambiará los espacios en blanco a +, lo que hará que funcione con los recuentos.
find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
| tr '[:blank:]' '+'
| awk '( NR%2 != 0){printf("%s ",$0);next}1 '
| awk '{print length($1)" "length($2)" "$1$2}'