Eu tenho a seguinte árvore de diretórios:
.
└── aaa
└── bbb
└── ccc
E crie um link simbólico:
ln -s ~/test/aaa/bbb slink
Depois disso, executo o comando tree:
tree -l
e veja
.
├── aaa
│ └── bbb
│ └── ccc
└── slink -> /home/kaa/test/aaa/bbb [recursive, not followed]
Por que o slink é marcado como recursivo? É um bug ou estou entendendo mal alguma coisa?
Responder1
Você usou a -l
opção:
Segue links simbólicos se apontarem para diretórios, como se fossem diretórios. Links simbólicos que resultarão em recursão são evitados quando detectados.
Agora, a razão pela qual ele imprime este aviso não é que isso seriana verdaderecurso. Podemos ver claramente que simplesmente listaria a bbb/ccc
árvore novamente.
O respectivo código éaqui, por falar nisso. Se o número do inode do diretório apontado pelo link simbólico for encontrado na tabela hash (aquela que é preenchida com saveino
e findino
), ele simplesmente irá ignorá-lo.
Responder2
Acho que a documentação é imprecisa. A documentação diz
Links simbólicos que resultarão emrecursãosão evitados quando detectados
mas deveria dizer algo como
Links simbólicos que resultarão emum diretório já visitadonão são seguidos
Verlocalização da mensagem de erro emtree.c
e
funcionar findino
emhash.c
.
tree -l
lembra dos diretórios visitados e só desce paralinkscujo alvo ainda não foi visitado:
( mkdir test1 && cd test1 && mkdir -p a/b && ln -s a link && tree -l; )
.
├── a
│ └── b
└── link -> a [recursive, not followed]
Observe que ignorar diretórios já visitados só é feito paralinks.Realdiretórios são sempre visitados. Isso significa quea ordem da travessia é importante. Atravessar exatamente a mesma árvore em ordem alfabética reversa ( -r
) segue o link, porque ele visita o link em um momento em que seu destino ainda não foi visitado.
( cd test1 && tree -r -l; )
.
├── link -> a
│ └── b
└── a
└── b
Aqui estão mais duas alternativas para reproduzir esse comportamento:
Ignore -I
o diretório ( ) a/
, para que ele não seja visitado ao visitar o link:
( cd test1 && tree -l -I a; )
.
└── link -> a
└── b
Nomeie os diretórios e o link, para que o link seja visitado naturalmente primeiro:
( mkdir test2 && cd test2 && mkdir -p x/y && ln -s x link && tree -l; )
.
├── link -> x
│ └── y
└── x
└── y