No meu servidor, eu tenho uma estrutura de diretórios parecida com esta:
/myproject/code
Normalmente, tenho uma conexão ssh com o servidor e 'fica' nesse diretório:
root@machine:/myproject/code#
Quando implanto uma nova versão do meu código, o diretório de código é removido, então fico com:
root@machine:/myproject/code# ./run
-bash: ./run: No such file or directory
E a única solução que encontrei é entrar e sair de CD:
root@machine:/myproject/code# cd ../code
root@machine:/myproject/code# ./run
Running...
Posso evitar isso? É um comportamento um tanto estranho. Se você tem uma boa explicação sobre o porquê disso, eu agradeceria.
shell
command-line
directory
cd-command
Markus Johansson
fonte
fonte
run
é igual ao diretório antigo. Ele tem apenas o mesmo nome e diretório pai. Compare isso com você destruindo seu carro antigo e comprando um carro exatamente da mesma cor e modelo: você não gostaria de ficar sentado no carro desfiado e espero que acabe ileso com o novo, não é?cd ../code
não é um noop...
é um atalho para o pai do caminho que você possui ou costumava ter. Se o diretório atual for excluído, o caminho pai ainda poderá existir e, nesse caso, poderá ser alcançado através da avaliação..
. Nesse diretório, é feita uma pesquisa por um diretório com o nome 'código'.Respostas:
Como arquivos e diretórios são fundamentalmente inodes do sistema de arquivos , não nomes - esse talvez seja um detalhe de implementação específico para o tipo de sistema de arquivos, mas é verdade para todos os sistemas ext, portanto, eu continuarei aqui.
Quando um novo diretório
code
é criado, ele é associado a um novo inode, e é aí que ele está. Não há registros mantidos de arquivos e diretórios excluídos anteriormente; portanto, não há meios pelos quais o sistema possa verificar qual inode costumava ocupar e talvez embaralhar as coisas para que sejam iguais novamente; esse sistema rapidamente se tornaria impraticável e, em qualquer caso, provavelmente não há garantia de que você voltaria lá novamente - isso seria algo indesejável, pois significa que você também pode acabar acidentalmente em outro lugar se um diretório for criado que leva seu inode (atualmente não usado).Não tenho certeza se essa última possibilidade existe ou se o inode do diretório excluído atualmente atribuído ao seu diretório de trabalho atual é rastreado para que nada seja atribuído a ele pela duração, etc.
fonte
Seu shell não faz sempre
cd
o caminho que estava durante o último comando, antes de executar o próximo comando.Você excluiu o diretório atual e criou um diretório com o mesmo nome, que não é o mesmo diretório, apenas algo com o mesmo nome / caminho.
Navegadores de arquivos como o Nautilus e o Windows Explorer normalmente "sobem" na árvore de diretórios se um diretório for excluído em um sistema de arquivos local. No entanto, isso nem sempre é verdade para sistemas de arquivos em rede; nesse caso, às vezes, a exclusão não é notada e o reaparecimento pode fazer com que você acabe no novo diretório.
Um shell pode
cd
entrar no diretório atual antes de executar o próximo comando, não conheço nenhum que faça (ou pode ser configurado para fazer isso).fonte
Na maioria dos sistemas do tipo UNIX, o "diretório atual" de um processo é armazenado no kernel como um descritor de arquivo apontando para esse diretório. O kernel não armazena o caminho do diretório atual: essas informações são rastreadas pelo seu shell.
Um objeto do sistema de arquivos (arquivo ou diretório) só é destruído para sempre quando todos os links do sistema de arquivos desaparecem e não há descritores de arquivo apontando para esse objeto.
Portanto, se um diretório for removido enquanto ainda houver um processo mantendo-o como seu diretório de trabalho atual, os processos
cwd
impedirão que o diretório seja realmente excluído. Os links do sistema de arquivos que ancoram o diretório (sua entrada no diretório pai e todo o seu conteúdo) desaparecerão, mas o próprio diretório continuará a existir como uma espécie de "zumbi". Enquanto isso, você pode criar um novo diretório no mesmo local que o antigo, que é um objeto de sistema de arquivos completamente diferente, mas que compartilha o mesmo caminho.Assim, quando você faz
cd ../code
(ou, em muitos shellscd .
), você está realmente percorrendo a hierarquia do sistema de arquivos e indo para o novo diretório que reside no endereço antigo.Por analogia, remover um diretório seria como mover uma casa à força para o depósito de lixo (romper vínculos com o endereço anterior). Se ainda houvesse alguém morando lá (usando-o como seu
cwd
), eles teriam que sair antes que a casa pudesse ser arrasada. Enquanto isso, uma casa nova em folha pode ser construída no antigo endereço.fonte
Razões limpas pelo @Anthon, por que isso acontece
Como solução, você pode usar o alias , como exemplo:
os aliases do bash são mantidos em ~ / .bashrc
fonte
Confirmação O diretório de trabalho atual É baseado no número do inode, não no que você procurou para chegar lá. Como você está usando o bash, você pode usar $ PWD da seguinte maneira para cd no novo diretório com o mesmo nome:
cd $ PWD
Para ilustrar, criei um comando fictício deploy:
Criou a primeira implementação, cd'd para codificar e depois verificou o conteúdo
ls -lai
para que você possa ver os inodes:Agora execute a 2ª implantação
E verifique o conteúdo do diretório ... agora não há nada no diretório! nem mesmo '.' e '..'! A partir disso, você pode ver que o bash não está usando a entrada de diretório '..' quando você executa,
cd ..
já que '..' não existe mais - presumo que seja parte de seu tratamento com $ PWD. Alguns outros shell mais antigos / não lidamcd ..
com essa situação, você deve primeiro procurar um caminho absoluto.Cd para
$PWD
e tente novamente:Observe como o inode para o diretório atual (.) Mudou?
Se o script de implantação moveu o diretório antigo para outro nome, por exemplo,
mv code code.$$
no script de implantação acima,./run
funcionaria, mas até você usá-cd $PWD
lo, você estaria executando o código antigo , não o novo.A implantação usando o capistrano tem o mesmo problema (eles têm um link simbólico do nome atual para o release atual), portanto, eu uso aliases para fazer o cd nas áreas de produção / preparação, além de definir RAIL_ENV adequadamente:
fonte
O caminho para alguma coisa é como você chega lá, não a coisa em si. O caminho para a sua cama pode ser através do seu quarto, mas quando você estiver na cama, se alguém a pegar e a levar para fora, você não estará mais no seu quarto.
fonte
Não é uma resposta independente, mas tenho um ponto adicional, que a margem de comentários era pequena demais para conter.
Para ter uma idéia melhor da idéia de que um diretório nos sistemas de arquivos relevantes é mais do que apenas um caminho, tente mover o diretório de trabalho atual de outro processo: em um shell, inicie uma sessão interativa do Python:
Em seguida, vá para outro shell e mova esse diretório:
De volta ao original:
fonte