tl; dr - A expansão de Bash é complicada para evitar loops infinitos de links simbólicos (em bash >= 4.3
), e você e eu interpretamos erroneamente o que ele estava fazendo nos comandos que você postou
Suponho que você tenha bash >= 4.3
, pois não consigo reproduzir o que você descreve em bash 4.2.46
, ele faz um loop até atingir um limite de recursão (conforme esperado).
Comentei isso por um tempo e configurei um diretório de teste para reproduzir o que imita a sua situação. O ponto crucial disso é como a expansão bash acontece em cada um dos seus exemplos. A expansão se comporta de maneira diferente dependendo se ela é ou não seguida por um /
, e que há apenas alguma dissonância cognitiva nesse ponto para nós, primatas, ao examinar exemplos como esse.
Na documentação do bash shopt :
globstar
If set, the pattern ‘**’ used in a filename expansion context will match all files and zero or more directories and subdirectories. If the pattern is followed by a ‘/’, only directories and subdirectories match.
Para ilustrar aqui minha configuração de teste:
$ mkdir -p test/nested
$ cd test
$ touch sneaky
$ touch nested/sneaky
$ cd nested
$ ln -s . looper
$ cd ..
resultando nessa estrutura de diretório:
test/
- sneaky
- nested/
- sneaky
- looper -> ./
Isso duplica suas descobertas no meu diretório de teste:
$ for apath in ../**/sneaky; do echo "$apath"; done
../test/nested/looper/sneaky
../test/nested/sneaky
../test/sneaky
$ printf "%s\n" ../** | grep sneaky
../test/nested/sneaky
../test/sneaky
No primeiro exemplo, o glob expande para (test/nested/looper, test/nested, test)
, parando em looper
sem seguir o link porque o glob foi seguido por /
Em seguida, adicionamos /sneaky
a isso, resultando no conjunto (test/nested/looper/sneaky, test/nested/sneaky, test/sneaky)
.
No segundo exemplo, o glob expande para (test/nested/looper, test/nested/sneaky, test/nested, test/sneaky, test)
(que você pode verificar removendo o | grep sneaky
)
Mais uma vez, essa expansão não segue o link looper
, mas, nesse caso, não acrescentamos /sneaky
a ela, descartando ../test/nested/looper/sneaky
de nossos resultados.
Por outro lado, continuamos a receber ../test/nested/sneaky
e ../test/sneaky
porque o glob também captura arquivos quando não é seguido por /