Por curiosidade, executei o seguinte:
mkdir haha
cd haha
ln -s ../haha haha
O que criou uma estrutura recursiva como esta:
┌────────┐
V │
haha/ │
haha/────┘
Eu queria ver o quão fundo eu poderia ir nisso, então digitei cd haha/
e segurei Tabpara que o bash preenchesse automaticamente um monte de haha/
s. Ele foi preenchido automaticamente até cd haha/haha/<SNIP>/haha/
(um total de 40 "haha/"s) antes de parar de completar repentinamente (comportamento estranho nº 1). Eu pressionei Enter. Correndo pwd
, vi que estava mesmo no diretório /home/me/haha/<SNIP>/haha/haha
(41 "haha/"s). De dentro deste diretório, executei outro cd haha
, que de repente me teletransportou de volta /home/me/haha
(conforme confirmado por outro pwd
). Huh? Por que isso acontece, é uma peculiaridade do bash? Limite do sistema de arquivos (estou usando btrfs)? Algo mais?
Quando você faz
cd haha/haha/...
ou realmente usa qualquer link simbólico de caminho, o kernel precisa resolver os links para descobrir para onde o caminho aponta. No Linux, há um limite para quantos links ele resolve antes de sair com "Muitos níveis de links simbólicos" (ELOOP).A página man path_resolution(7) menciona esse limite de 40 links:
Quando você repete a conclusão da guia, o que acontece é que o shell solicita uma listagem de diretórios de
haha/
, entãohaha/haha/
, etc. até que em algum momento o sistema operacional se recusa a reproduzir e elimina o erro. Parece que a rotina de preenchimento de tabulação não expõe esse erro ao usuário, provavelmente para não causar muito ruído. Se você tentassecd haha/...
com um caminho muito longo, receberia o erro. Mas com um caminho que está abaixo do limite, funciona.Por padrão, o shell tenta lembrar o caminho que você usou para chegar a um diretório, de modo que
pwd
mostra o caminho com links, e issocd foo; cd ..
leva você de volta ao ponto de partida, independentemente de serfoo
um link.Quando estiver no limite, fazer isso
cd haha
leva o Bash a chamar primeirochdir(".../haha/haha")
com todo o caminho, que agora tem muitos links, e a chamada falha. Depois disso, o shell para de tentar ser sofisticado e apenas chamachdir("haha")
e resolve a localização atual comgetcwd()
, obtendo um caminho sem nenhum link.