Onde o comando find procura primeiro se existem diretórios com o mesmo nome?

0

Suponha que eu tenha dois diretórios diferentes com os mesmos nomes de pastas:

/usr/myDir / e /home/myDir/

Se eu executar um comando como:

cd $(find / -type d -name myDir)

navega para /usr/myDir . Por que é que? Onde o comando find procura primeiro quando se trata de instâncias especiais como essa?

    
por Roflicide 05.02.2016 / 00:16

2 respostas

1

find atravessa arquivos na ordem em que o sistema de arquivos retorna. Esta ordem não é previsível; criar, remover ou renomear um arquivo pode alterar a ordem de outros arquivos no mesmo diretório.

É uma disputa se find / -type d -name myDir retorna /usr/myDir ou /home/myDir primeiro, e isso pode mudar a qualquer momento. (Neste exemplo específico, ele provavelmente não mudará com frequência, porque é raro gravar no diretório raiz, mas em geral não conte com isso.)

Em alguns shells (incluindo o bash), o comando cd ignora todos, exceto seus primeiros argumentos, portanto, seu comando silenciosamente altera o diretório de trabalho para qualquer que seja o find retornar primeiro. (Seu comando também wouldn ' t trabalho para um caminho contendo espaços .) Em outros shells (como ksh e zsh), você receberia uma mensagem de erro.

    
por 06.02.2016 / 01:07
3

Existem dois problemas; como cd se comporta, o que é fácil de testar via:

bash-4.1$ mkdir first second
bash-4.1$ cd first second
bash-4.1$ pwd
/home/jdoe/first
bash-4.1$ 

Então, cd para este shell está indo para o primeiro item encontrado. Segundo, find pode ou não fazer qualquer classificação dos resultados e, para diretórios (provavelmente), tem apenas uma opção -d ou "localizar primeiro por profundidade", que retornaria /some/deeper/dir antes de /some ou %código%. Assim, você fica com o retorno da chamada do sistema, / de um rápido getdents(2) de strace no Linux. Essas entradas nunca devem ser consideradas classificadas em uma ordem específica (a menos que algo como find as ordene para você):

bash-4.1$ mkdir c ; sleep 5
bash-4.1$ mkdir b ; sleep 5
bash-4.1$ mkdir a ; sleep 5
bash-4.1$ find .
.
./b
./c
./a

Em caso de dúvida, você precisará impor algum tipo de ordenação nos resultados, pois, por padrão, ls encontrará o que a chamada de sistema subjacente para o sistema de arquivos retorna primeiro.

    
por 05.02.2016 / 00:59