通过Java运行linux命令和shell脚本出现异常

问题描述 投票:0回答:1

我正在使用这个java方法进行系统调用来运行linux命令和shell脚本:

public String executeShellCommand(String linuxCommand) {

        String commandOutput;
        ProcessBuilder processBuilder;
        String [] command = {
                "/bin/bash",
                "-c",
                linuxCommand
        };

        try {
            log.debug("Making system call : [{}]",String.join(" ", command));
            // Execute the shell command
            processBuilder = new ProcessBuilder(command);
            Process p = processBuilder.start();
            BufferedReader br = new BufferedReader(
                    new InputStreamReader(p.getInputStream()));
            if ((commandOutput = br.readLine()) != null) {
                p.waitFor();
                log.trace("exit: " + p.exitValue());
                p.destroy();
                return commandOutput;
            }

        } catch (Exception e) {
            log.error("Exception in running shell command {}", linuxCommand, e);
        
            return null;
        }
       
        log.trace("There was no output for the given command {} that was executed", linuxCommand);
        return "";
    }

每次 cron 计划每 6 小时运行一次 java 进程时,我都会收到以下异常(当 JVM 执行该进程时成功,但随后当调度程序每 6 小时运行一次时失败,即使是在第一次调度程序运行时),但是有趣的是,当 cron 设置为每 15 或 30 分钟运行一次时,它会成功(尝试运行 24 小时,并成功完成 30 分钟的所有运行):

java.io.IOException: Cannot run program "/bin/bash": error=0, Failed to exec spawn helper: pid: 2009, exit value: 127
        at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1143) ~[na:na]
        at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1073) ~[na:na]
        at com.oracle.gbucs.database.exporter.provisioning.service.ShellCommandService.executeShellCommand(ShellCommandService.java:41) ~[classes!/:2024.2.6]
        at com.oracle.gbucs.database.exporter.provisioning.service.ProvisioningService.runExporterProvisioningScript(ProvisioningService.java:395) ~[classes!/:2024.2.6]
        at com.oracle.gbucs.database.exporter.provisioning.service.ProvisioningService.provisionExporterForOneDatabase(ProvisioningService.java:167) ~[classes!/:2024.2.6]
        at com.oracle.gbucs.database.exporter.provisioning.controller.ProvisioningController.provisionExporters(ProvisioningController.java:106) ~[classes!/:2024.2.6]
        at com.oracle.gbucs.database.exporter.provisioning.controller.ProvisioningController.scheduled(ProvisioningController.java:142) ~[classes!/:2024.2.6]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:84) ~[spring-context-5.3.21.jar!/:5.3.21]
        at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.3.21.jar!/:5.3.21]
        at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:95) ~[spring-context-5.3.21.jar!/:5.3.21]
        at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) ~[na:na]
        at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
        at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
Caused by: java.io.IOException: error=0, Failed to exec spawn helper: pid: 2009, exit value: 127
        at java.base/java.lang.ProcessImpl.forkAndExec(Native Method) ~[na:na]
        at java.base/java.lang.ProcessImpl.<init>(ProcessImpl.java:314) ~[na:na]
        at java.base/java.lang.ProcessImpl.start(ProcessImpl.java:244) ~[na:na]
        at java.base/java.lang.ProcessBuilder.start(ProcessBuilder.java:1110) ~[na:na]
        ... 19 common frames omitted

Linux 命令的示例,通过 Java 运行时失败,但直接在命令行中执行时工作正常:

用于计算服务器上当前运行的脚本数量的命令 -

ps -ef | grep oracledb_exporter | grep -v grep | wc -l

Java 版本是 17.0.5,我在远程服务器(SSH 会话)上运行它。我还仔细检查了我的服务器上是否有 bash。我在这里缺少什么?

java bash exception
1个回答
0
投票

错误 java.io.IOException: Cannot run program "/bin/bash": error=0, Failed to exec spawn helper: pid: 2009, exit value: 127 表明 cron 作业运行的环境存在问题,可能是由于环境变量、权限或系统资源的差异造成的。确保 cron 环境包含必要的路径和权限,并考虑使用 ProcessBuilder.environment().put() 直接在 Java 代码中设置环境变量。通过比较手动运行和 cron 作业的环境进行调试,并在必要时调整系统资源限制。

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