Existem muitas razões para uma falha de segmentação. A causa mais comum de baixo nível é que o processo tentou acessar um endereço de memória que não está definido, isto é, um desreferenciamento de ponteiro inválido. Isso geralmente é um bug no programa.
Aqui, você está executando um programa shell. O shell é uma linguagem de programação de alto nível, sem ponteiros, portanto, seu script não pode causar uma desreferência de ponteiro inválida como tal.
Muitos programas têm espaço limitado para sua pilha de chamadas e morrem de uma falha de segmentação quando o tamanho da pilha é excedido. Na maioria dos casos, o limite de tamanho da pilha é grande o suficiente para qualquer dado razoável, mas uma recursão infinita pode explodir a pilha.
No bash, a recursão infinita em uma chamada de função causa uma falha de segmentação. (O mesmo vale para traço e mksh; o ksh e o zsh são mais inteligentes e aplicam uma profundidade máxima de aninhamento de chamadas de função no nível do shell para que não sejam segmentados).
Seu script tem vários bugs. O que está te mordendo é que, no caso de um arquivo regular, você sempre chama recurse
no final, enquanto você claramente queria fazê-lo apenas para arquivos zip.
Não use &&
ou ||
quando você quer dizer if
. É mais claro escrever o que você quer dizer; a brevidade através da obscuridade não é uma boa ideia e aqui você mordeu.
if [[ ${extension} = "zip" ]]; then
unzip -uq $currentItem -d "${extractionDirectory}"
recurse ${extractionDirectory}
fi
Outro erro é que você está perdendo aspas duplas em torno de substituições de variáveis , assim o seu programa irá sufocar em nomes de arquivos contendo espaço em branco (entre outros). Sempre use aspas duplas em torno de substituições de variáveis, a menos que você saiba que precisa desativá-las.
Use a expansão de parâmetro em vez de chamar basename
e dirname
. É mais fácil lidar com casos especiais (por exemplo, nome de arquivo que começa com -
) e é mais rápido.
Outro erro que eu encontrei é que o padrão +(sh|xslt|dtd|log|txt)
é claramente destinado a ser @(sh|xslt|dtd|log|txt)
(corresponde a essas extensões, não shsh
, dtdtxtshdtd
etc.).
Aqui está o caso de arquivo normal, com os erros acima corrigidos e reescritos com case
para maior clareza:
case "$extension" in
sh|xslt|dtd|log|txt) break;;
zip)
extractionDirectory=$"{currentItem%.zip}"
unzip -uq "$currentItem" -d "${extractionDirectory}"
recurse "${extractionDirectory}"
esac
Note que não verifiquei a lógica ou testei o código. Esta parece ser uma maneira complicada de escrever
find -type f -name '*.zip' -exec sh -c 'unzip -uq "$0" -d "${0%.zip}"' {} \;