我必须在 Linux 机器中从 Java 运行 shell 脚本 例如, 下面是脚本路径以及脚本所需的所有参数。
"ksh /xyz/abc/data/code_base/RUN_SCRIPTS/dev/my_script.sh param1 param2 20200901 459 121"
下面是代码,
String script = "ksh /xyz/abc/data/code_base/RUN_SCRIPTS/dev/my_script.sh param1 param2 20200901 459 121";
ProcessBuilder processBuilder = new ProcessBuilder();
processBuilder.command(script);
processBuilder.redirectErrorStream(true);
//start() will be in try catch
process = processBuilder.start();
int exitVal = process.waitFor();
if(exitVal == 0){
//code
}
我是否需要通过将每个脚本添加为列表中的单独字符串来将脚本作为列表传递? “ksh”,“/xyz/abc/data/code_base/RUN_SCRIPTS/dev/my_script.sh”,“param1”“param2”“20200901”“459”“121”
在我的 Windows 机器上,我打开一个记事本,如下所示,它工作正常,
ProcessBuilder processBuilder = new ProcessBuilder("Notepad.exe", "C:/Dev/Test.txt");
processBuilder.redirectErrorStream(true);
process = processBuilder.start();
脚本会在 Linux 机器上正确执行吗?还是需要对代码进行更多更改??
你应该能够使用
Runtime.exec()
或ProcessBuilder
来调用shell来运行脚本,但整个过程充满了陷阱。
我建议阅读这篇文章:
https://www.infoworld.com/article/2071275/when-runtime-exec---won-t.html
这解释了许多这些陷阱以及如何避免它们。特别是,在 Linux 上,您几乎肯定需要从 shell 调用中使用 stdout 和 stderr —— 即使脚本不产生任何输出,有时也是如此。您还需要小心如何处理脚本参数中的空格和特殊字符(如果有的话)。 Java 用于命令行的解析器会盲目地在空格处中断命令行。
看看这个 Runtime.getRunTime().exec
您还可以使用我的小型图书馆,名为 jaxec:
import com.yegor256.Jaxec;
String stdout = new Jaxec("my_script.sh", "param1", "param2")
.withHome("/home/me") // run it in this directory
.withRedirect(false) // don't redirect STDERR to STDOUT
.exec();
Jaxec
类的实例不仅会执行您的脚本,还会将其输出发送到Slf4j日志,等待其完成,将stderr重定向到stdout,并确保如果退出代码不等于则引发异常零。在幕后,Jaxec
使用 Runtime
。