Linux: Como um diretório poderia ser criado sem “.” e “..”?

6

Não tenho certeza se o seguinte problema é específico do busybox: Eu tenho um dispositivo incorporado com o busybox instalado. Pelo que entendi, quando um diretório é criado, geralmente dois arquivos ocultos serão criados automaticamente: . para representar o diretório atual e .. para representar o diretório pai. Por exemplo, digitando mkdir -p /tmp/normal_dir; cd /tmp/normal_dir; ls -a , a saída será . .. .

No entanto, tenho visto um caso em que um diretório existente ( /tmp/strange_dir ) não mostra . e .. . Ou seja, digitando cd /tmp/strange_dir; ls -a , a saída está vazia, embora a navegação para o diretório pai ainda funcione. Ou seja, digitando cd .. , o conteúdo está correto.

Minha pergunta é: Como esse diretório sem . e .. (como /tmp/strange_dir ) pode ser criado? Estou intrigado.

    
por jonathanzh 18.08.2015 / 03:37

3 respostas

3

Isso pode acontecer se você estiver acessando o diretório por meio de um symlink, mas o diretório vinculado é removido. Por exemplo, em /tmp , vamos criar um diretório e um link simbólico para esse diretório:

$ cd /tmp
$ mkdir normal_dir
$ ln -s normal_dir strange_dir

Agora, se navegarmos para strange_dir , obtemos a saída esperada:

$ cd strange_dir
$ ls -a
. ..

Se, no entanto, removermos o diretório normal_dir sem alterar o diretório, na verdade, obteremos um resultado interessante:

$ rmdir /tmp/normal_dir
$ ls -a

$ ls -al
total 0

Portanto, embora nosso link agora aponte para nada, o "diretório" de trabalho do shell ainda é o mesmo:

$ pwd
/tmp/strange_dir

$ cd /tmp/strange_dir
bash: cd: /tmp/strange_dir: No such file or directory

$ ls -al
total 0

A execução de stat -L . enquanto o nosso diretório de trabalho ainda estiver em /tmp/strange_dir mostrará agora Size: 0 conforme discutido nos comentários acima. Embora a saída de ls não mostre nada agora (nem mesmo . nem .. ), pode ainda navegar muito bem até o diretório pai .. nesse caso, conforme descrito:

$ cd ..
$ pwd
/tmp

$ ls -a
. .. strange_dir

Embora o link simbólico ainda exista, ele não aponta para nada, então não podemos cd voltar para strange_dir neste ponto, a menos que o diretório /tmp/normal_dir seja re criado. Para limpar, basta remover o link simbólico chamando rm /tmp/strange_dir .

    
por 19.08.2015 / 12:41
1

É concebível que tal aberração possa ser criada se alguém disser

mkdir /tmp/strange_dir

no momento em que o sistema de arquivos estava cheio (ou seja, não havia blocos livres). Ainda seria (provavelmente) possível criar o strange_dir entrada de diretório em /tmp , porque isso exigiria apenas alguns bytes de espaço não utilizado em um dos blocos já alocados para /tmp . Mas teria sido impossível alocar um bloco para strange_dir , e, portanto, teria sido impossível para criar as entradas . e .. . Nesse caso, Eu esperaria que o programa mkdir fosse removido (desvincular) a entrada do diretório strange_dir em /tmp , mas o software nem sempre faz o que eu espero.

Outras possibilidades:

  • mkdir foi interrompido (terminado) entre a criação da entrada de diretório strange_dir em /tmp e criar as entradas . e .. em strange_dir . Eu esperaria mkdir para capturar o sinal de interrupção (isto é, Ctrl + C ) e limpar depois de si, mas veja acima sobre software e minhas expectativas sobre isso. E, claro, não pode capturar o sinal de kill ou uma falha no sistema.
  • rmdir foi interrompido (terminado) entre desvincular as entradas . e .. em strange_dir e desvinculando a entrada de diretório strange_dir em /tmp .

Pode-se esperar que o fsck seja executado após uma falha iria detectar o strange_dir e fazer algo sobre isso, mas ....

Sim, claro, se um diretório tiver um tamanho de 0, isso significa que não tem blocos alocados para ele, e, portanto, não pode ter qualquer conteúdo (nem mesmo pequenos como . e .. ).

Não entendo totalmente por que cd .. funcionaria quando não há .. , mas veja a discussão em Removendo um diretório de dentro usando a interface de linha de comando . Acontece que

mkdir /tmp/strange_dir
cd /tmp/strange_dir
ls -lai                 ← Shows normal . and .., with inode numbers.
rmdir /tmp/strange_dir
pwd                     ← Still reports /tmp/strange_dir
ls -lai                 ← Shows empty directory: Total 0
ls -ldi                 ← Shows . with the same inode number it had before,
                          but with a size of 0 and a link count of 0.
cd ..                   ← Puts you back into /tmp

Esta situação não é perfeitamente análoga à desta questão, porque, neste outro caso, strange_dir é removido de /tmp . Mas isso sugere que cd .. é especial e, às vezes, funciona quando não há um mecanismo óbvio pelo qual possa funcionar.

Diferença estranha entre pwd e / bin / pwd sugere uma possibilidade sobre como isso pode funcionar. O shell mantém o controle do seu diretório atual. Ou seja, ele controla o melhor palpite quanto ao seu diretório atual. Pode ser enganado por links simbólicos e truques como

mkdir /tmp/foo
cd /tmp/foo
mv /tmp/foo /tmp/foobar

, ou seja, ainda achará que o diretório atual é /tmp/foo , e é isso que pwd informará, mas pwd -P e /bin/pwd reportarão /tmp/foobar . Então, pode ser que, se chdir("..") falhar, o shell calcula o que deve ser seu diretório de próximo nível, e vai lá absolutamente. (Mas eu suspeito que há mais do que isso.)

    
por 19.08.2015 / 11:15
0

Obrigado pelas discussões até agora. A seguir, uma explicação de um colega meu que não é membro da comunidade Super User:

/tmp/strange_dir no meu caso é um diretório NBD / VFS (Network Block Device / Virtual File System). Esse tipo de sistema de arquivos virtual difere dos sistemas de arquivos mais tradicionais e possui sua própria implementação dos comandos do shell. Portanto, não é surpreendente que, quando o diretório estiver vazio, ls -a não mostre nada, mas cd .. permite ir até seu diretório pai.

    
por 27.08.2015 / 17:10

Tags