我需要在symlink目录中从Java运行本机进程.我们有以下目录结构:
guido@Firefly:~/work$ tree
.
??? path
??? to
??? symlink -> /home/guido/work
3 directories, 0 files
Run Code Online (Sandbox Code Playgroud)
我从~/work目录启动Java应用程序,并希望在目录中运行本机进程~/work/path/to/symlink.
但是,如果我使用以下Java代码,则符号链接工作目录将解析为实际路径.相反,我想在绝对路径中运行命令.
(请注意,该pwd命令仅用于说明,应替换为"真实"命令(例如go build在我的情况下)).
File baseDir = new File("/home/guido/work");
File link = new File(baseDir, "path/to/symlink");
Files.createSymbolicLink(link.toPath(), baseDir.toPath());
Process process = new ProcessBuilder()
.command("pwd")
.directory(link)
.start();
String output = getOutput(process);
System.out.println(output); // Prints: /home/guido/work
Run Code Online (Sandbox Code Playgroud)
我能够通过以下解决方法满足我的需求,但启动shell只是为了能够在特定目录中触发一个简单的进程看起来很愚蠢.另外,我失去了平台独立性.
String[] cmd = {"/bin/sh", "-c", "cd " + link + " && pwd"};
Process process = Runtime.getRuntime().exec(cmd);
String output = getOutput(process);
System.out.println(output); // Prints: /home/guido/work/path/to/symlink
Run Code Online (Sandbox Code Playgroud)
在这里,您可以找到一个完整的示例作为两个解决方案的单元测试要点.
小智 5
如果我理解正确,您希望进程将符号链接视为其工作目录,而不是符号链接目标.我怀疑这是可能的.Python也提出了类似的问题:
首先,JVM在运行进程时不解析符号链接.在分叉之后,它chdir()在子进程中调用系统调用,并解析符号链接:
接下来,getcwd()系统调用返回工作目录,保证返回其组件不是符号链接的路径:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/getcwd.html
您的解决方法适用于Bash,但它不适用于调用的进程getcwd().Bash有自己的版本pwd,(我猜)也会查看PWD环境变量(由设置cd).如果在变通方法中修改pwd为/usr/bin/pwd,则会显示符号链接目标.