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? ".