如何从 Java 运行通过 Homebrew 或 MacPorts 安装的工具?

问题描述 投票:0回答:2
  • 我正在尝试使用 Java 在 MacOS 上实现一些自动化。
  • 从终端手动运行命令时没有问题
  • 我认为它有效是因为
    <user.home>/.zprofile
  • 尝试通过 ProcessBuilder 执行命令时找不到这些命令

如何在与手动运行 zsh 终端相同的环境中执行命令?

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Test {
  public static void main(String[] args) throws Exception {
    // these commands work
    run("/bin/sh", "-c", "echo $PATH");
    run("/bin/bash", "-c", "echo $PATH");
    run("/bin/zsh", "-c", "echo $PATH");

    // these commands all work when I run them manually in a terminal
    // but fail here with "zsh:1: command not found: ..."
    run("/bin/zsh", "-c", "node -v");
    run("/bin/zsh", "-c", "npm -v");
  }

  private static void run(String... command) throws Exception {
    ProcessBuilder processBuilder = new ProcessBuilder();
    processBuilder.redirectErrorStream(true);
    processBuilder.command(command);
    Process process = processBuilder.start();
    try(BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
      for(String line = br.readLine(); line != null; line = br.readLine()) {
        System.out.println(line);
      }
    }
    System.out.println("return value: " + process.waitFor());
  }
}

输出:

/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
zsh:1: command not found: node
return value: 127
zsh:1: command not found: npm
return value: 127
java macos shell homebrew processbuilder
2个回答
0
投票

在阅读了太多有关 shell 的文章并研究了 shell 初始化图之后,我决定使用 Zsh。

原因是这篇博文,它表明Zsh似乎至少有一个初始化文件,可以为所有可能的shell变体执行(登录、非登录、交互式、非交互式等)。

我将所有环境设置(路径和 LANG)移至

/etc/zshenv
,删除了
/etc/zprofile
和所有
~/.z*
文件。

我还将 root 和我的用户的 shell 更改为 Zsh(对于用户,这也可以通过系统首选项来完成):

  dscl . -delete /Users/root UserShell && dscl . -create /Users/root UserShell /bin/zsh && dscl . -read /Users/root UserShell
  dscl . -delete /Users/reto UserShell && dscl . -create /Users/reto UserShell /bin/zsh && dscl . -read /Users/reto UserShell

现在我得到了相同的环境:

  • SSH 作为 root
  • 以用户身份使用 SSH
  • 终端.app
  • 从 Java 启动的进程
  • 到目前为止几乎所有其他事情

到目前为止一切顺利。测试程序输出:

/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
/opt/local/bin:/opt/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
return value: 0
v14.17.0
return value: 0
6.14.13
return value: 0

0
投票

我最近自己遇到了这个问题,感觉我在整个网络上寻找对此的解释。 基本上,bash 或 zsh 中设置的路径不会“转移”到从 java 运行的进程。

所以解决这个问题的方法是你必须通过环境变量手动添加路径。

这里添加了自制程序的路径,例如:

// Get the current environment variables
Map<String, String> environment = System.getenv();

// Add Homebrew binary path to the system's PATH
String brewPath = "/usr/local/bin:/opt/homebrew/bin";
String currentPath = environment.get("PATH");
String newPath = brewPath + ":" + currentPath;

// Use ProcessBuilder to run the command
ProcessBuilder processBuilder = new ProcessBuilder("bash", "-c", command);
processBuilder.environment().put("PATH", newPath);

Process process = processBuilder.start();

        
© www.soinside.com 2019 - 2024. All rights reserved.