Encontrando o comprimento dos arquivos e o caminho do arquivo da estrutura de diretórios em um sistema de arquivos Linux

Encontrando o comprimento dos arquivos e o caminho do arquivo da estrutura de diretórios em um sistema de arquivos Linux

Eu tenho um problema em um sistema operacional Linux executando uma versão do SMB onde se o caminho absoluto para um diretório dentro de uma pasta compartilhada formaior que 1024 bytes e o componente do nome do arquivo for maior que 256 byteso serviço SMB trava e bloqueia todos os outros serviços para acesso à rede, como SSH e FTP, deixando a máquina sem som.

Para evitar que o sistema trave, movi temporariamente um grupo de pastas onde acho que o caminho do problema pode estar localizado fora da pasta compartilhada. Preciso encontrar o arquivo e o caminho do arquivo que excedeu essa limitação e renomeá-los ou removê-los, permitindo-me retornar uma grande parte dos arquivos para a pasta compartilhada.

Eu tentei oencontraregrepcomandos sem sucesso. Existe uma cadeia de comandos ou script que posso usar para localizar os arquivos e diretórios incorretos?

Por favor, avise.

Responder1

Isso é escrito em Bash e usa recursos específicos (mas recursos semelhantes estão disponíveis em outros shells). Ele foi projetado para ser executado a partir de um diretório pai comum a todos os arquivos e diretórios nos quais você está interessado. Ele leva em consideração o comprimento do caminho até /lá e o adiciona ao comprimento de cada caminho avaliado. Se você não quiser fazer isso, basta usar lenpwd=0em vez de lenpwd=${#PWD}. Funcionará se houver arquivos com espaços em seus nomes, mas não aqueles que possuem novas linhas (que devem ser banidas de qualquer forma). Ele imprime os comprimentos e especificações de arquivo de qualquer coisa que encontrar que atenda aos critérios.

lenpwd=${#PWD}; find | while read -r path; do file=${path##*/}; if (( ${#path} + lenpwd > 1024 || ${#file} > 256 )); then echo "$((${#path} + lenpwd)) ${#file} $path"; fi; done

Responder2

Não sei se entendi direito, mas primeira tentativa:

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

Este é apenas um script eu-não-testei-mas-deveria-funcionar-no-bash-an-equlas-shell. Sinta-se à vontade para adicionar verificação de erros e outras coisas úteis ...

Responder3

Aqui está uma linha que exibe o comprimento do nome do dir, depois o comprimento do nome da base, depois o nome do dir e por último o nome da base (para a posteridade). Acabei de usar o diretório de trabalho atual, mas isso pode ser alterado. Isso também pode ser expandido para extrair os valores maiores do que os dados.

find `pwd` -exec dirname '{}' \; -exec basename '{}' \;
 | awk '( NR%2 != 0){printf("%s ",$0);next}1 '
 | awk '{print length($1)" "length($2)" "$1$2}'

Atualizar:

Para classificar pelo comprimento do dirname, adicione isto ao final:

 | sort -nr

Para classificar pelo comprimento do nome base, adicione isto ao final:

 | sort -nr -k2

Atualização 2:

De acordo com o comentário do autor, isso mudará o espaço em branco para +, o que fará com que funcione com as contagens.

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}'

informação relacionada