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

2

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

Para manter o sistema em risco, movi temporariamente um grupo de pastas nas quais acredito que o caminho do problema pode estar localizado fora da pasta compartilhada. Eu 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 os comandos find e grep sem sucesso. Existe uma cadeia de comandos ou script que eu possa usar para procurar os arquivos e diretórios ofensivos?

Por favor, informe.

    
por Robert Nickens 01.06.2010 / 14:10

3 respostas

1

Isso é escrito no Bash e usa recursos específicos para ele (mas recursos similares 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 de / até lá e o adiciona ao comprimento de cada caminho avaliado. Se você não quiser fazer isso, use lenpwd=0 em vez de lenpwd=${#PWD} . Ele funcionará se houver arquivos com espaços em seus nomes, mas não aqueles que tenham novas linhas (que devem ser banidas de qualquer forma). Imprime os comprimentos e filespec de qualquer coisa 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
    
por 01.06.2010 / 14:48
0

Não sei se entendi sua correção, mas a 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 que não deve ser testado, mas deve ser trabalhado no bash-equlas-shell. Sinta-se à vontade para adicionar verificação de erros e outras coisas úteis ...

    
por 01.06.2010 / 14:51
0

Aqui está um one-liner que exibe o comprimento do nome do diretório, o tamanho do nome de base, o nome do diretório e o sobrenome (para a posteridade). Acabei de usar o diretório de trabalho atual, mas isso pode ser alterado. Isso também pode ser expandido para classificar os valores maiores 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}'

Atualização:

Para classificar por comprimento de nome de diretório, adicione isso ao final:

 | sort -nr

Para classificar por tamanho de nome de base, adicione isso ao final:

 | sort -nr -k2

Atualização 2:

Por comentário do autor, isso alterará o espaço em branco para +, o que fará com que ele 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}'
    
por 01.06.2010 / 16:10