Sua função analisa a saída sem aspas de ls
. Isso significa que o shell executará a divisão de palavras (por padrão, em qualquer espaço em branco) e a geração de nome de arquivo (globbing) na saída de ls
.
Em vez disso:
dirwalk () {
indent=${1:-0}
for name in *; do
[ ! -e "$name" ] && continue
if [ -d "$name" ]; then
printf '%*sDir: "%s"\n' "$indent" "" "$name"
( cd "$name" && dirwalk "$(( indent + 4 ))" )
else
printf '%*sFile: "%s"\n' "$indent" "" "$name"
fi
done
}
ou, sem o recuo fantasia,
dirwalk () {
for name in *; do
[ ! -e "$name" ] && continue
if [ -d "$name" ]; then
printf 'Dir: "%s"\n' "$name"
( cd "$name" && dirwalk )
else
printf 'File: "%s"\n' "$name"
fi
done
}
Usando *
em vez da saída de ls
, geramos uma lista de nomes de arquivos adequadamente delimitada para fazer a iteração no diretório atual, mesmo que contenham espaços.
O teste -e
é certificar-se de que a coisa que nós iteramos realmente existe. Se inserirmos um diretório vazio, o *
não se expandiria e permaneceria como *
. Em bash
, você pode definir a opção nullglob
shell (com shopt -s nullglob
) para fazer com que padrões incomparáveis sejam expandidos para nada.
Usando cd
em um subshell (entre parênteses), não precisamos lembrar de cd ..
para voltar ao diretório anterior. O ambiente fora de ( ... )
não seria afetado pelo cd
dentro dele.
Usando printf
em vez de echo
, temos maior controle sobre a formatação da saída. Veja também " Por que printf é melhor que echo? ".