这里是新的 Linux 用户,刚刚从 Windows 10 过渡到 Fedora 41。对许多操作系统有丰富的经验,包括各种 *nix 和类 Unix 文件系统。
我有一个标准做法,即使用从测试文件夹到代码存储库的符号链接,以便在本地重新创建已部署的生产文件夹结构以进行测试,同时保持测试和代码存储库完全分离。我有许多像这样设置的项目用于本地测试。
例如,如下所示:
~/dev
test
a-project
app => ../../code/a-project/src
(cfg)
(web)
dta
cfg
code
a-project
src
cfg
web
这个问题的关键在于src/cfg
文件夹(在生产环境中就是app/cfg
文件夹)包含的文件具有对可选文件的相对引用,dta/cfg
如果这些文件在生产环境中存在,则加载这些文件,这些文件应相对于文件夹。app/cfg
因此,../../dta/cfg/Optional.json
部署时会引用dta
文件夹。PWD 是应用程序根目录(在测试环境中,这是~/dev/test/a-project
并且软件中的所有路径都是相对于 PWD 指定的。这些路径在 Java 代码中使用 Java 的类进行操作File
,因此这不是 shell 行为问题。
这在 Windows 上运行良好,因为文件系统将路径app/cfg/../../dta/cfg/Optional.json
理解为其确切的含义,并首先解析相对引用,从而导致dta/cfg/Optional.json
(前导app/cfg
被以下消除../..
)。
但是 Linux 显然首先解析符号链接( app/cfg/
=>dev/code/project/src/)
然后才应用相对路径段../../dta/cfg/Optional.json
,导致找不到文件,因为该文件当然不在中~/dev/code/project/dta/cfg
。
不管这在技术上是否正确,有没有什么方法可以让我在任何级别告诉 Linux 在解析符号链接之前解析相对路径段,以免发生这种意外和不可预测的行为?除了让我感到困惑和违反直觉之外,我有很多现有的代码,它们期望路径首先解析相对引用,即使用表观路径,而不是底层路径。
我的开发工作所用的文件系统是启用了大小写折叠的 ext4(来自 Windows,需要与使用 Mac 和 Windows 的其他开发人员保持兼容),我真的非常希望避免在将路径传递给操作系统之前对一堆 Java 类进行不稳定的侵入性更改以实现相对路径解析;因为它可能很脆弱,导致安全漏洞,而且它只需要用于我的测试,因为生产系统(Ubuntu Linux 服务器)不需要这些符号链接。
简单的答案是“不”。如果不更改 Java 代码,符号链接将无法执行您所要求的操作。
为什么?
那是因为
..
它不是你所想的那样……这种行为并非不可预测。它之所以令人惊讶,只是因为该
cd
命令做了一些奇怪的事情。在所有其他情况下,..
内核都会将其解释为文件系统中的真实事物。每个目录实际上都包含一个名为的子目录..
,该子目录直接引用其父目录。因此
foo/..
告诉内核跟随符号链接foo
,然后在该目录中查找名称..
。内核实际上并没有做与路径不同的任何事情foo/bar
。选项
替代配置布局
观察结果显示:您遇到的问题似乎是由于您的配置也存储在源代码目录中。这是一种不寻常的模式。
通常,您会将配置放在测试目录中,使其特定于测试。配置可能引用应用程序的位置,或者您的运行脚本知道布局。
您始终可以将单个配置文件符号链接到
test/app/cfg
目录中。只要目录路径本身不是符号链接,配置文件本身的实际路径就可以是符号链接。使用绑定挂载/docker
我个人更喜欢使用绑定挂载来实现这种类型,并且为此我通常使用 Docker 和 docker compose 作为设置测试的方式。
您可能更喜欢使用 shell 脚本来为您设置绑定挂载,因为 java 通常需要某种运行脚本。
例如:测试目录中的docker-compose.yaml文件
也可以在脚本中使用
unshare
和mount --bind
finally手动设置。但这更复杂。exec