【问题标题】:Source command not working through Java源命令无法通过 Java 运行
【发布时间】:2015-07-12 18:31:54
【问题描述】:

从昨天开始,我一直在尝试使用 JAVA 在终端 (MAC) 上执行命令,但无论我做什么都没有用。

我想要执行以下 2 个命令并在 JAVA 中返回输出

source activate abc_env
python example.py

到目前为止,我已经尝试了以下方法,没有任何输出

String[] command = new String[] { "source activate abc_env", "python example.py"};
String result = executeCommands(command);

这是我的 executeCommands 方法

private static String executeCommands(String[] command) {

        StringBuffer output = new StringBuffer();

        Process p;
        try {
            for(int i=0; i< command.length;i++)
            {
                p = Runtime.getRuntime().exec(command[i]);
                p.waitFor();
                BufferedReader reader = 
                                new BufferedReader(new InputStreamReader(p.getInputStream()));

                String line = "";           
                while ((line = reader.readLine())!= null) {
                    output.append(line + "\n");
                }
                System.out.println("Error output: " + p.exitValue());
                System.out.println("Output:" + output);

            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("Here");
        }
        return output.toString();
    }

这给了我以下异常

无法运行程序“源”:错误=2,没有这样的文件或目录

我在网上搜索,有人说源不会这样工作,我应该将命令更改为

String[] command = new String[] { "bash -c 'source activate abc_env'", "python example.py"};

现在,我没有收到异常,但命令仍然不起作用,它返回 '2' 作为 exitValue()

然后我尝试将命令作为脚本执行

#!/bin/bash
source activate abc_env
python example.py

当我将 .sh 文件作为字符串读取并将其传递给命令时,出现以下异常

无法运行程序“#!/bin/bash”:错误=2,没有这样的文件或目录

那么,我的问题是如何通过 Java 正确运行源命令和 python 命令?我的最终目标是从 Java 中执行一些 python。

编辑1: 如果我尝试以下命令并打印输出流

String[] command = {
                "/bin/bash",
                "-c",
                "source activate cvxpy_env"
        };

executeCommand(command));

输出流:

退出值:1

ErrorOutput:/bin/bash: activate: 没有这样的文件或目录

如果我尝试相同的命令,但在 'source activate abc_env' 周围加上单引号。我得到以下输出

退出值:127

ErrorOutput:/bin/bash: source activate cvxpy_env: command not found

解决方案:

String[] command = {
                "/bin/bash",
                "-c",
                "source /Users/pc_name/my_python_library/bin/activate abc_env;python example.py"
        };

【问题讨论】:

  • 为了更清楚一点,linux中的这个“/Users/pc_name/my_python_library/bin/activate/”可以翻译成Anaconda的安装路径,如:“/opt/anaconda /bin/激活”。因此:source /opt/anaconda/bin/activate abc_env(如果 abc_env 是您的环境名称)。

标签: java python bash terminal


【解决方案1】:

根据 Javadoc,Runtime.exec(String) 使用 StringTokenizer 将命令拆分为 command-args 列表,这可能会将您的命令拆分为:

bash
-c
'source
activate
abc_env'

这显然不是你想要的。您应该做的可能是使用接受现成参数列表的Runtime.exec(String[]) 版本,并将其传递给new String[] {"bash", "-c", "source activate abc_env"}

现在,要了解它为什么不工作,您不仅应该阅读它的stdout,还应该阅读stderr,使用p.getErrorStream()。只需将您阅读的内容打印出来,这将是一个很好的调试辅助工具。

回复:您的编辑。现在它看起来工作正常,就 Java 和 bash 而言。输出“activate: No such file or directory”可能是source 命令成功运行的输出。只是source 找不到activate 文件。它在工作目录中吗?如果没有,您可能应该拥有"cd /wherever/your/files/are; source activate cvxpy_env"。哦,如果你的 python 脚本依赖于 source 命令的任何副作用,你可能必须在同一个 bash 实例中执行它,即:

String[] command = {
                "/bin/bash",
                "-c",
                "cd /wherever/your/files/are && source activate cvxpy_env && python example.py"
        };

或者更好的是,将其全部打包到一个 shell 脚本中,然后只需 Runtime.exec("./my_script.sh")(不过不要忘记 chmod +x)。

【讨论】:

  • 我尝试了你提到的东西,但我仍然有一个错误。我已经更新了我的问题。请参阅 EDIT1。
  • 好的,很好。我会尝试你的新答案,并会尽快更新你。要去开会。
  • 太棒了。我让它工作了。我刚刚包含了激活脚本的路径,它工作正常。谢谢。
【解决方案2】:

试试

String[] command = {
                "/bin/bash",
                "-c",
                "source activate abc_env; " + "python example.py"
        };

【讨论】:

  • 参见 EDIT1。我试过你提到的东西,但我仍然有错误。
  • @Behroz 您可能需要指定“activate”和“abc_env”脚本以及“example.py”的完整路径。错误告诉你它找不到文件。
  • /bin/bash
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-06-25
  • 2019-05-25
  • 1970-01-01
  • 2021-05-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多