Sou novo usuário de Linux aqui, recém-transferido do Windows 10 para o Fedora 41. Tenho muita experiência com muitos sistemas operacionais, incluindo vários sistemas de arquivos *nix e semelhantes ao Unix.
Tenho uma prática padrão de usar links simbólicos de pastas de teste para repositórios de código para recriar a estrutura de pasta de produção implantada localmente para teste, mantendo o teste e o repositório de código claramente separados. Tenho muitos projetos configurados assim para teste local.
Isto se parece com o seguinte, por exemplo:
~/dev
test
a-project
app => ../../code/a-project/src
(cfg)
(web)
dta
cfg
code
a-project
src
cfg
web
A chave para esse problema é que a src/cfg
pasta (que na produção é a app/cfg
pasta) contém arquivos que têm referências relativas a arquivos opcionais nos dta/cfg
quais são carregados se eles existirem na produção, esperados para serem relativos à app/cfg
pasta. Assim, ../../dta/cfg/Optional.json
quando implantado, faz referência à dta
pasta. O PWD é a raiz do aplicativo (em testes, isso é ~/dev/test/a-project
e todos os caminhos no software são especificados em relação ao PWD. Esses caminhos são manipulados em código Java, usando File
a classe Java, então este não é um problema de comportamento do shell.
Isso funciona perfeitamente no Windows, já que o sistema de arquivos considera o caminho app/cfg/../../dta/cfg/Optional.json
exatamente como ele parece e resolve as referências relativas primeiro, resultando em dta/cfg/Optional.json
(o inicial app/cfg
sendo eliminado pelo seguinte ../..
.
Mas o Linux aparentemente resolve o link simbólico primeiro ( app/cfg/
=> dev/code/project/src/)
e só então aplica os segmentos de caminho relativos ../../dta/cfg/Optional.json
, resultando em um arquivo não encontrado porque, é claro, o arquivo não está localizado em ~/dev/code/project/dta/cfg
.
Independentemente de argumentos sobre se isso é tecnicamente correto ou não, há alguma maneira de eu dizer ao Linux em qualquer nível para resolver segmentos de caminho relativos antes de resolver links simbólicos para que esse comportamento inesperado e imprevisível não ocorra? Além de ser confuso e contraintuitivo para mim, tenho muito código existente que espera que os caminhos resolvam referências relativas primeiro, ou seja, usando o caminho aparente, não o caminho subjacente.
O sistema de arquivos para meu trabalho de desenvolvimento é ext4 com case folding habilitado (vindo do Windows e precisando permanecer compatível com outros desenvolvedores usando Mac e Windows), e eu realmente, realmente gostaria de evitar fazer uma mudança desestabilizadora e invasiva em várias classes Java para implementar a resolução de caminho relativo antes de passar o caminho para o sistema operacional; tanto porque é potencialmente frágil, levando a falhas de segurança, quanto porque é necessário apenas para meus testes, já que sistemas de produção (servidores Ubuntu Linux) não precisam desses links simbólicos.
A resposta simples é "não". Sem alterar o código Java, os links simbólicos não farão o que você pede.
Por que?
Isso porque
..
não é o que você pensa...O comportamento não é imprevisível. Só é realmente surpreendente porque o
cd
comando faz algo estranho. Em todos os outros contextos,..
é interpretado pelo kernel como algo real no sistema de arquivos. Cada diretório na verdade contém um filho chamado..
que se refere diretamente ao seu pai.Então
foo/..
diz ao kernel para seguir o link simbólicofoo
e então procurar o nome..
naquele diretório. O kernel realmente não está fazendo nada diferente do que faria para o caminhofoo/bar
.Opções
Layout de configuração alternativo
Como observação: o problema que você enfrenta parece vir do fato de que sua configuração também está armazenada no diretório do seu código-fonte. Esse é um padrão incomum.
Normalmente, você colocaria a configuração no diretório de teste, tornando-a específica para o teste. A configuração pode referenciar o local do aplicativo ou seu script de execução conhece o layout.
Você sempre pode criar links simbólicos para arquivos de configuração individuais no
test/app/cfg
diretório. Desde que o caminho do diretório em si não seja um link simbólico, o caminho real do arquivo de configuração em si pode ser um link simbólico.Usar montagens de ligação / docker
Eu pessoalmente prefiro montagens de vinculação para esse tipo de coisa e, para esse propósito, geralmente uso o Docker e o Docker Compose como uma forma de configurar o teste.
Você pode preferir usar um script de shell para configurar montagens de vinculação para você, já que o Java geralmente requer algum tipo de script de execução.
Por exemplo: arquivo docker-compose.yaml no diretório de teste
Também é possível configurar isso manualmente usando
unshare
andmount --bind
e finallyexec
em um script. Mas isso é mais complexo.