代码之家  ›  专栏  ›  技术社区  ›  Simeon Leyzerzon mthmulders

通过Java进程生成器激活虚拟机

  •  1
  • Simeon Leyzerzon mthmulders  · 技术社区  · 8 年前

    尝试以编程方式激活python的 虚拟现实 通过下面的代码:

    java.io.IOException: Cannot run program "." (in directory "/Users/simeon.../..../reporting"): error=13, Permission denied
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
        at VirtualEnvCreateCmdTest.runCommandInDirectory(VirtualEnvCreateCmdTest.java:30)
        at VirtualEnvCreateCmdTest.createVirtEnv(VirtualEnvCreateCmdTest.java:61)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at ......
    Caused by: java.io.IOException: error=13, Permission denied
        at java.lang.UNIXProcess.forkAndExec(Native Method)
        at java.lang.UNIXProcess.<init>(UNIXProcess.java:247)
        at java.lang.ProcessImpl.start(ProcessImpl.java:134)
        at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
        ... 25 more
    

    代码:

    public class VirtualEnvCreateCmdTest {
    
        private final static Logger LOG = LoggerFactory.getLogger(VirtualEnvCreateCmdTest.class);
    
        private void runCommandInDirectory(String path,String ... command) throws Throwable
        {
    
            LOG.info("Running command '"+String.join(" ",command)+"' in path '"+path+"'");
    
    
            ProcessBuilder builder = new ProcessBuilder(command)
                    .directory(new File(path))
                    .inheritIO();
    
            Process pr = builder.start();
    
            final String failureMsg = format("Failed to run '%s' in path '%s'.  Got exit code: %d", join(" ",command), path, pr.exitValue());
            LOG.info("prepared message {}: ", failureMsg);
    
            if(!pr.waitFor(120, TimeUnit.SECONDS))
            {
                throw new Exception(failureMsg);
    
            }
    
    
            int output = IOUtils.copy(pr.getInputStream(), System.out);
    
            int exitCode=pr.exitValue();
    
            if(exitCode!=0)
                throw new Exception(failureMsg);
    
        }
    
        @Test
        public void createVirtEnv()  throws Throwable {
    
            String path = "/Users/simeon/.../reporting";
            String [] commands = new String[]{".", "activate"};
            //String [] commands = new String [] {"/bin/bash", "-c", ". /Users/simeon/..../venv2.7/bin/activate"};
            runCommandInDirectory(path, commands);
    
        }
    

    更改文件的权限似乎不起作用:

    chmod u+x ./bin/activate

    通过它做 /bin/bash 不过,还是有一个不同的错误。

    同时,以下命令行也可以正常工作:

    . /Users/simeon/.../venv2.7/bin/activate
    

    如何调用Java内部的Python VielalEnv激活命令的任何示例?

    ==有效的:=====

    以下是我的工作:

        private void runDjangoMigrate() throws Throwable {
    
            final String REPORTING_PROJECT_LOCATION = "/Users/simeon.../.../reporting";
            final String UNIX_SHELL_LOCATION = "/bin/bash";
            final String PYTHON_VIRTUALENV_ACTIVATOR_COMMAND =". /Users/simeon.../.../venv2.7/bin/activate;";
            final String PYTHON_VIRTUALENV_ACTIVATOR_COMMAND =". " + PYTHON_VIRTUALENV_ACTIVATE_SCRIPT_LOCATION + ";"; 
            final String DJANGO_MANAGE_MODULE = " manage.py";
    
            final String[] DJANGO_MIGRATE_COMMAND = new String[] { UNIX_SHELL_LOCATION, "-c", PYTHON_VIRTUALENV_ACTIVATOR_COMMAND
                    + PYTHON_INTERPRETER + DJANGO_MANAGE_MODULE + " migrate --noinput --fake-initial" };
    
            runCommandInDirectory(REPORTING_PROJECT_LOCATION, DJANGO_MIGRATE_COMMAND);
    
    
    }
    
    
        private void runCommandInDirectory(String path, String... command) throws Throwable {
    
            LOG.info(format("Running '%s' command in path '%s'", join(" ",command),path));
    
            ProcessBuilder builder = new ProcessBuilder(command).directory(new File(path)).inheritIO();
    
            Process pr = null;
    
            pr = builder.start();
    
            IOUtils.copy(pr.getInputStream(), System.out);  
    
            boolean terminated = pr.waitFor(SPAWNED_PYTHON_PROCESS_TTL_SEC, SECONDS);
    
            int exitCode = -1;
    
            if (terminated) {
    
                exitCode = pr.exitValue();
            }
    
            if (exitCode != 0) {
    
                final String failureMsg = format("Failed to run '%s' in path '%s'.  Got exit code: %d", join(" ", command),
                        path, pr.exitValue());
    
                throw new Exception(failureMsg);
            }
    
        }
    

    并产生以下预期产出:

    [java] System check identified some issues:
     [java]
     [java] WARNINGS:
     [java] ?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
     [java] Building permissions...
     [java] Operations to perform:
     [java]   Apply all migrations: admin, auth, contenttypes, sessions
     [java] Running migrations:
     [java]   No migrations to apply.
     [java] System check identified some issues:
     [java]
     [java] WARNINGS:
     [java] ?: (urls.W005) URL namespace 'admin' isn't unique. You may not be able to reverse all URLs in this namespace
     [java] Building permissions...
     [java] User exists, exiting normally due to --preserve
     [java] System check identified some issues:
     [java]
    
    1 回复  |  直到 8 年前
        1
  •  3
  •   phd    8 年前

    您可以在BASH(也许是ZSH)和Python中激活Python虚拟环境,但不能在Java或任何其他环境中激活。要理解的主要问题是,虚拟环境的激活不会产生系统魔力——激活脚本只是改变 当前环境 ,而python虚拟环境准备更改shell或python,但不更改其他内容。

    就Java而言,这意味着当你调用 runCommandInDirectory() 它运行一个新的shell,新shell简单地激活虚拟的Env,但是shell退出,所有激活“虚拟EnV”的改变都消失了。

    这反过来意味着,如果需要在虚拟环境中运行一些shell或python命令,则必须在 RunCommandIndirectory() 调用:

    String [] commands1 = new String [] {"/bin/bash", "-c", ". /Users/simeon/..../venv2.7/bin/activate; script1.sh"};
    runCommandInDirectory(path, commands)
    
    String [] commands2 = new String [] {"/bin/bash", "-c", ". /Users/simeon/..../venv2.7/bin/activate; script2.sh"};
    runCommandInDirectory(path, commands)
    

    对于python脚本,可以运行 python 从环境中自动激活环境:

    String [] commands = new String [] {"/Users/simeon/..../venv2.7/bin/python", "script.py"};
    runCommandInDirectory(path, commands)