Estou correto em entender como links simbólicos e '..' interagem sob POSIX

3

Estou trabalhando em uma descrição matemática de caminhos (como caminhos de arquivos, mas também mais abstratos e gerais)

Uma das coisas mais difíceis de definir é o comportamento de .. (φ no post vinculado); particularmente com a forma como interage com links simbólicos.

Eu quero verificar se entendi bem as regras do POSIX.

POSIX 4.14 diz

When a process resolves a pathname of an existing directory entry, the entire pathname shall be resolved as described below. When a process resolves a pathname of a directory entry that is to be created immediately after the pathname is resolved, pathname resolution terminates when all components of the path prefix of the last component have been resolved. It is then the responsibility of the process to create the final component. ... Each filename in the pathname is located in the directory specified by its predecessor (for example, in the pathname fragment a/b, file b is located in directory a). ... If a symbolic link is encountered during pathname resolution, ... the system shall prefix the remaining pathname, if any, with the contents of the symbolic link ... the resolved pathname shall be the resolution of the pathname just created. If the resulting pathname does not begin with a , the predecessor of the first filename of the pathname is taken to be the directory containing the symbolic link. The special filename dot shall refer to the directory specified by its predecessor. The special filename dot-dot shall refer to the parent directory of its predecessor directory. As a special case, in the root directory, dot-dot may refer to the root directory itself. ..

Então, o que eu entendo é que POSIX diz que os links simbólicos devem ser expandidos antes de resolver .. para ir para o diretório pai.

Isso está correto?

Portanto, para normalizar caminhos, a maneira compatível com POSIX é o comportamento de %código% que é exigir a existência de todos os diretórios (mas não o componente final do arquivo) e expandir a resolução de links simbólicos da esquerda para a direita (assim que é encontrado) e, em seguida, aplicar realpath -P O que quer dizer que o sistema de arquivos tem que ser lido em todas as etapas de processamento de um caminho.

Podemos contrastar isso com o comportamento de .. do node.js (ou mesmo é Path.normalize ) - o que eu acho bastante normal em muitos idiomas de programação ( Python2 e 3 Path.posix.normalize são semelhantes). O que equivale a os.path , o que significa dizer que ignora completamente que alguns diretórios podem ser simlinks, ou podem não existir. O que é legal, já que não precisa tocar no sistema de arquivos.

Se nós pegarmos um caminho que tenha sido normalizado dessa maneira, e dar a uma função que toque no sistema de arquivos (por exemplo, realpath -s -m ) Então é equivalente a se tivéssemos normalizado o caminho usando fs.readFile , que é "Resolver realpath -L antes de links simbólicos"

Bash .. também age como se tivesse processado o argumento com cd , a menos que você forneça o realpath -L flag

Estou entendendo corretamente a especificação POSIX e sua relação com -P e com muitas bibliotecas de caminho de linguagem de programação (a maioria?)?

Pergunta bônus: - P, alguém tem um exemplo de linguagens / bibliotecas de programação (além de usar utilitários shell como realpath ) que tem uma implementação de normalização compatível com POSIX? (Acredito que o Python 3 pathlib.Path.resolve esteja correto. converte caminhos relativos para caminhos absolutos.)

    
por Lyndon White 15.09.2016 / 07:34

2 respostas

2

Você está correto em sua compreensão das especificações do POSIX. Faz sentido quando você olha para ele a partir da perspectiva de que os diretórios são apenas nós no sistema de arquivos, apontando para outros nós que têm nomes. Os nós especiais de . e .. apontam para os nós literais não para um caminho (string).

A maioria das funções de manipulação de cadeias de caminho da biblioteca de programação são agnósticas para o conteúdo real do sistema de arquivos, portanto, devem necessariamente ser normalizadas simplesmente pela manipulação de cadeias de caracteres. A vantagem disso é que eles podem normalizar caminhos que não existem ou que não têm acesso à leitura.

Para normalizar caminhos na forma POSIX, você precisará normalizar .. usando caminhos absolutos em vez de relativos, pois não fará sentido. Um caminho symlink poderia ter apontado para uma parte completamente diferente do sistema de arquivos, onde um caminho relativo não faz mais sentido ou exigiria outro .. para alcançar. Se você quiser, pode usar o readlink e algumas regras para descobrir se você pode usar um caminho relativo, mas não acho que nenhuma das bibliotecas de caminhos tenha funções para descobrir isso.

    
por 15.09.2016 / 08:53
1

. e .. em Unixes são entradas de diretório reais que representam arquivos reais (arquivos ou diretórios) que pertencem ao diretório pai.

.. não é uma palavra-chave de resolução de caminho para remover o último segmento do caminho. Para resolver um .. , primeiro você precisa resolver o diretório que o contém. Nodejs está fazendo errado.

$ mkdir -p /tmp/foo/bar/baz
$ ln -s /tmp/foo/bar/baz /tmp/symlink
$ realpath /tmp/symlink/..
  /tmp/foo/bar
$ node -e 'console.log(path.normalize("/tmp/symlink/.."))'
  /tmp

(Estas entradas são sempre criadas quando um diretório é criado, e elas são feitas para serem hardlinks para o diretório atual e para seu pai. Eles são alguns dos raros exemplos de hardlinks de diretório , como os sistemas normalmente não permitem que usuários comuns façam hardlinks de diretórios.

É por isso que a contagem de hardlinks nas listagens ls -ld aumenta para um diretório sempre que você cria um subdiretório e por que os diretórios começam na contagem 3 do hardlink (seu nome,. e nome_seua / ..). O .. dos subdiretórios é um link físico para o diretório atual e, portanto, aumenta sua contagem de hardlinks. )

    
por 15.09.2016 / 08:38