
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=0
em 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}'