Digamos que eu entre no shell de um sistema unix e comece a digitar os comandos. Inicialmente, começo no diretório inicial do meu usuário ~
. Eu poderia de lá cd
para o diretório Documents
.
O comando para alterar o diretório de trabalho aqui é muito simples de entender intuitivamente: o nó pai possui uma lista de nós filhos que ele pode acessar e, presumivelmente, usa uma variante (otimizada) de uma pesquisa para localizar a existência de um nó filho com o nomeie o usuário digitado e o diretório de trabalho será "alterado" para corresponder a isso - me corrija se eu estiver errado lá. Pode até ser mais simples que o shell simplesmente "ingênuo" tente acessar o diretório exatamente conforme os desejos do usuário e, quando o sistema de arquivos retornar algum tipo de erro, o shell exibirá uma resposta de acordo.
No entanto, estou interessado em saber como o mesmo processo funciona quando navego em um diretório, ou seja, para um pai ou pai.
Dada minha localização desconhecida, presumivelmente "cega" de Documents
, um dos possivelmente muitos diretórios em toda a árvore do sistema de arquivos com esse nome, como o Unix determina onde eu devo ser colocado em seguida? Faz uma referência pwd
e examina isso? Se sim, como pwd
acompanha o estado atual de navegação?
fonte
Respostas:
As outras respostas são simplificações excessivas, cada uma apresentando apenas partes da história, e estão erradas em alguns pontos.
Há duas maneiras pelas quais o diretório de trabalho é rastreado:
chdir()
e dofchdir()
sistema, e a última porchroot()
. Pode-se vê-los indiretamente nos/proc
sistemas operacionais Linux ou através dofstat
comando no FreeBSD e similares:Quando a resolução do nome do caminho opera, ela começa em um ou outro daqueles vnodes referenciados, dependendo se o caminho é relativo ou absoluto. (Há uma família de
…at()
chamadas de sistema que permitem que a resolução do nome do caminho comece no vnode referenciado por um descritor de arquivo aberto (diretório) como uma terceira opção.)No microkernel Unices, a estrutura de dados está no espaço do aplicativo, mas o princípio de manter referências abertas a esses diretórios permanece o mesmo.
chdir()
.Se alguém mudar para um nome de caminho relativo, ele manipula a string para acrescentar esse nome. Se alguém mudar para um nome de caminho absoluto, ele substituirá a sequência pelo novo nome. Nos dois casos, ajusta a sequência para remover
.
e..
componentes e perseguir links simbólicos, substituindo-os pelos nomes vinculados. ( Aqui está o código do shell Z para isso , por exemplo).O nome na variável de cadeia interna é rastreado por uma variável de shell denominada
PWD
(oucwd
nos shells C). Isso é convencionalmente exportado como uma variável de ambiente (nomeadaPWD
) para programas gerados pelo shell.Estes dois métodos de coisas rastreamento são reveladas pelos
-P
e-L
opções para ocd
epwd
shell built-in comandos e pelas diferenças entre as conchas Built-inpwd
comandos e tanto o/bin/pwd
comando e o built-inpwd
comandos de coisas como (entre outros) VIM e NeoVIM.Como você pode ver: obter o diretório de trabalho "lógico" é uma questão de olhar para a
PWD
variável shell (ou variável de ambiente, se não for o programa shell); enquanto que obter o diretório de trabalho "físico" é uma questão de chamar agetcwd()
função de biblioteca.A operação do
/bin/pwd
programa quando a-L
opção é usada é um pouco sutil. Ele não pode confiar no valor daPWD
variável de ambiente que herdou. Afinal, ele não precisa ter sido chamado por um shell e os programas intervenientes podem não ter implementado o mecanismo do shell de tornar aPWD
variável de ambiente sempre rastrear o nome do diretório de trabalho. Ou alguém pode fazer o que eu fiz lá.Então, o que ele faz é (como o padrão POSIX diz) verificar se o nome fornecido
PWD
produz a mesma coisa que o nome.
, como pode ser visto em um rastreamento de chamada do sistema:Como você pode ver: ele só chama
getcwd()
se detectar uma incompatibilidade; e pode ser enganado definindoPWD
uma cadeia que de fato nomeia o mesmo diretório, mas por uma rota diferente.A
getcwd()
função de biblioteca é um assunto em si. Mas précis:..
diretório. Ele parou quando atingiu um loop em que..
era o mesmo que seu diretório de trabalho ou quando ocorreu um erro ao tentar abrir a próxima..
. Seria muitas chamadas de sistema ocultas.No entanto, observe que mesmo no FreeBSD e nesses outros sistemas operacionais, o kernel não controla o diretório de trabalho com uma string.
Navegar para
..
é novamente um assunto em si. Outra característica: embora os diretórios convencionalmente (embora, como já mencionado, isso não seja necessário) contenham um real..
na estrutura de dados do diretório no disco, o kernel rastreia o diretório pai de cada diretório do próprio nó e, portanto, pode navegar para o..
nó de qualquer diretório de trabalho. Isso é um pouco complicado pelo ponto de montagem e pelos mecanismos raiz alterados, que estão além do escopo desta resposta.a parte, de lado
Windows NT, de fato, faz uma coisa semelhante. Há um único diretório de trabalho por processo, definido pela
SetCurrentDirectory()
chamada da API e rastreado por processo pelo kernel por meio de um identificador de arquivo aberto (interno) para esse diretório; e há um conjunto de variáveis de ambiente que os programas Win32 (não apenas os intérpretes de comando, mas todos os programas Win32) usam para rastrear os nomes de vários diretórios de trabalho (um por unidade), anexando-os ou substituindo-os sempre que eles mudam de diretório.Convencionalmente, diferentemente do caso dos sistemas operacionais Unix e Linux, os programas Win32 não exibem essas variáveis de ambiente para os usuários. Às vezes, é possível vê-los em subsistemas do tipo Unix em execução no Windows NT, bem como usando os comandos dos intérpretes de
SET
comando de uma maneira específica.Leitura adicional
pwd
" . The Open Group Base Specifications Issue 7. IEEE 1003.1: 2008. O grupo aberto. 2016.fonte
..
no contexto do Plan9,.
e..
componentes e perseguir links simbólicos, substituindo-os por seus nomes vinculados. … O nome na variável interna da string é rastreado por uma variável do shell chamadaPWD
… ”(ênfase adicionada). ... (continua)PWD
=…/b
após umcd b
comando, mesmo queb
seja um link simbólico paraa
- para que o shell não “persiga” oa -> b
link. Você deturpou ou interpretou mal?CHASE_LINKS
,.O kernel não controla os nomes de diretório ou arquivo; um arquivo ou diretório é representado no kernel por um par inode / dispositivo. Chamadas de sistema, como
chdir()
,open()
, etc. tomar um caminho como parâmetro, que pode ser absoluta (por exemplo/etc/passwd
), ou relativos ao diretório atual (exemplos:Documents
,..
). Quando um processo é executadochdir("Documents")
, é feita uma pesquisaDocuments
no diretório de trabalho atual e o diretório de trabalho do processo é atualizado para se referir a esse diretório. Da perspectiva do kernel, não há nada de especial no nome "..", é apenas uma convenção no sistema de arquivos que..
se refere ao diretório pai.A
getcwd()
função não é uma chamada de sistema, mas uma função de biblioteca que precisa ir até o diretório raiz, registrando os nomes dos componentes do caminho no caminho.fonte
Curiosamente, tradicionalmente
cd ..
é muito, muito mais simples do quepwd
. Diretórios nomeados..
são colocados explicitamente no sistema de arquivos. O sistema controla o dispositivo / inode do diretório atual; portanto,cd ..
ou com mais precisão, a chamada do sistemachdir("..")
implica procurar o nome ".." no arquivo pertencente ao inode do diretório atual e alterar o dispositivo / inode do diretório atual para o diretório valor encontrado lá.pwd
(com mais precisão/bin/pwd
) segue os..
links sucessivamente e lê os respectivos diretórios até encontrar o inode de onde veio, montando a lista desses nomes em ordem inversa até atingir o diretório raiz (principalmente sem conter uma..
entrada).Agora, este é o comportamento básico de baixo nível original. Em
pwd
vez disso, os comandos shell reais contam com uma variedade de técnicas que armazenam em cache o nome do caminho atual. Mas, no fundo, é apenas o seu inode que é realmente conhecido. Isso implica que, uma vez que os links simbólicos sejam usados para navegar nos diretórios, as noções atuais de nome do diretório de trabalho do shell atual e do sistema/bin/pwd
poderão divergir.fonte