O que acontece quando o diretório atual é excluído?

2

No primeiro terminal A, eu crio um diretório, digito o diretório e crio um arquivo:

$ mkdir test
$ cd test
$ touch file1.txt
$ ls
file1.txt

Então, em outro terminal B, eu apago o diretório:

$ rm -r test
$ mkdir test
$ cd test
$ touch file2.txt

E de volta o terminal A (não fazendo nenhum cd ), eu tento listar os arquivos:

$ ls

ls não vê nada e também não reclama.

O que acontece no fundo? Como é que ls não vê o problema? E existe uma maneira padrão, portátil e / ou recomendada de descobrir que algo não está correto no terminal A?

pwd apenas imprime o nome do diretório aparentemente correto. touch file3.txt não diz nenhum arquivo ou diretório que não seja útil. Apenas bash -c "pwd" fornece duas linhas de erro que, de alguma forma, revelam que algo está errado, mas não é realmente descritivo, e não tenho certeza de quão portátil isso é entre sistemas diferentes (estou no Ubuntu 16.04). cd .. && cd test corrige o problema, mas não explica realmente o que aconteceu.

    
por wenzeslaus 30.03.2018 / 03:18

1 resposta

4

How comes that ls doesn't see the problem?

Não há "problema" em primeiro lugar.

something is not right in the terminal A

Não há nada que não esteja certo. Existem semânticas definidas para processos que têm diretórios não-ligados abertos, assim como existem semânticas definidas para processos que abrem arquivos não-vinculados. Ambos são coisas normais.

Existem semânticas definidas para desvincular uma entrada de diretório que referenciou algo (embora tenha algo aberto em algum lugar) e então criar uma entrada de diretório pelo nome original ligando para algo mais : Você agora tem dois desses somethings, e referenciando a descrição aberta para o primeiro não acessa o segundo, ou vice-versa. Isso é tão verdadeiro para diretórios quanto para arquivos.

Um processo pode ter uma descrição de arquivo aberto para um diretório por meio de:

  • sendo o diretório de trabalho do processo;
  • sendo o diretório-raiz do processo;
  • sendo aberto pelo processo que chamou a função de biblioteca opendir() ; ou
  • sendo aberto pelo processo que chamou a função de biblioteca open() .

rmdir() tem permissão para não remover links para um diretório ainda aberto (que era o comportamento de alguns antigos Unices e é o comportamento de alguns sistemas não compatíveis com POSIX não-UNIX-Linux) e é < em> required falhar se o diretório ainda aberto for desvinculado por meio de um nome que termine em um componente de nome de caminho . ; mas se for bem-sucedido e remover o link final para o diretório, a semântica definida será um diretório ainda aberto, mas desvinculado:

  • não tem entradas de diretório em todos ;
  • não pode ter entradas de diretório criadas depois disso, mesmo que o processo de tentativa tenha acesso de gravação ou acesso privilegiado.

Seu sistema operacional é um dos que não retorna EBUSY de rmdir() nessas circunstâncias, e seu shell na primeira sessão de terminal tem um diretório desvinculado, mas ainda aberto, como seu diretório atual. Tudo o que você viu foi o comportamento definido nessa circunstância. ls , por exemplo, mostrou o diretório vazio em aberto primeiro , dos dois diretórios que você tinha naquele ponto.

Até mesmo a saída de pwd foi. Quando executado como um comando interno naquele shell, esse shell mantinha o controle interno do nome do diretório atual em uma variável shell / environment. Quando executado como um comando interno em outro shell, o outro shell não correspondia ao dispositivo e ao número do nó i de seu diretório de trabalho ao segundo diretório agora denominado pelo conteúdo do PWD variável de ambiente que herdou, decidindo não confiar no conteúdo de PWD , e então falhando na função de biblioteca getcwd() porque o diretório de trabalho não possui nenhum nome por mais tempo, tendo sido desvinculado.

Leitura adicional

por 30.03.2018 / 06:51