Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在symlink目录中运行Java进程?_Java_Symlink - Fatal编程技术网

如何在symlink目录中运行Java进程?

如何在symlink目录中运行Java进程?,java,symlink,Java,Symlink,我需要在symlink目录中从Java运行本机进程。让我们有以下目录结构: guido@Firefly:~/work$ tree . └── path └── to └── symlink -> /home/guido/work 3 directories, 0 files 我正在从~/work目录启动Java应用程序,并希望在~/work/path/to/symlink目录中运行本机进程 但是,如果我使用以下Java代码,符号链接工作目录解析为。相反,我希望在

我需要在symlink目录中从Java运行本机进程。让我们有以下目录结构:

guido@Firefly:~/work$ tree
.
└── path
    └── to
        └── symlink -> /home/guido/work

3 directories, 0 files
我正在从
~/work
目录启动Java应用程序,并希望在
~/work/path/to/symlink
目录中运行本机进程

但是,如果我使用以下Java代码,符号链接工作目录解析为。相反,我希望在中运行命令。

(请注意,
pwd
命令仅用于说明,应替换为“真实”命令(例如,在我的情况下,
go build

File baseDir=新文件(“/home/guido/work”);
文件链接=新文件(baseDir,“path/to/symlink”);
createSymbolicLink(link.toPath(),baseDir.toPath());
流程=新的ProcessBuilder()
.命令(“pwd”)
.目录(链接)
.start();
字符串输出=getOutput(进程);
System.out.println(输出);//打印:/home/guido/work
我能够通过以下解决方法满足我的需求,但启动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
String[]cmd={”/bin/sh“,“-c”,“cd”+link+”&&pwd“};
processprocess=Runtime.getRuntime().exec(cmd);
字符串输出=getOutput(进程);
System.out.println(输出);//打印:/home/guido/work/path/to/symlink

在这里,您可以找到两种解决方案的完整示例。

如果我理解正确,您希望流程将符号链接视为其工作目录,而不是符号链接目标。我怀疑这是可能的。Python也提出了类似的问题:

首先,JVM在运行进程时不会解析符号链接。分叉后,它在子进程中调用
chdir()
系统调用,从而解析符号链接:

接下来,工作目录由
getcwd()
系统调用返回,该调用保证返回其组件不是符号链接的路径:


您的变通方法适用于Bash,但不适用于调用
getcwd()
的进程。Bash有自己版本的
pwd
,它(我猜)也会查看
pwd
环境变量(由
cd
设置)。如果在变通方法中将
pwd
修改为
/usr/bin/pwd
,它将显示符号链接目标。

,因为另一个答案表明可能无法使用符号链接实现此功能,但可能还有另一种方法。您可以使用绑定挂载。有关更多详细信息,请参阅或。简言之:

mkdir -p /path/to
mount -o bind /home/guido/work /path/to/symlink

这将在路径中装载一个新文件系统,作为相同目录和文件的新视图。Java应用程序应该正确解析路径。另一方面,符号链接更为方便,可以在不使用根的情况下创建,因此这是一种奇特的解决方案。尽管如此,如果它足够重要的话,也许这是一条出路?

这可以通过以下解决方法满足我的需要,但是启动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

符号链接就是这样做的。解析到真正的路径。不清楚您在问什么,我在问如何在symlink目录中运行Java进程
pwd
只是一个示例命令,我需要将其替换为“真实”命令。我将稍微修改一下描述;然后File f=新文件(path.toRealPath(LinkOption.NOFOLLOW_LINKS.toString());您得到了预期的结果,但将其传递给ProcessBuilder.directory似乎意味着ProcessBuilder遵循符号链接,因为它不会停留在link@EJP我修改了描述,所以希望更清楚,我不是在询问符号链接的行为。您的测试用例在我的mac上按预期/按您的需要工作。因此,您可以将操作系统信息更新到Q。这是一个很好的答案,可以解释问题。然而,这对我的问题没有帮助:我正在编写一个Java应用程序(一个Gradle插件),因此我对用户的环境没有任何控制权——我只能进行操作系统检查并对其做出反应。