背景
我正在写一个运行 .sh
中指定的文件 .properties
并获取其返回值。道路 .sh
文件指定自 .properties
文件如下:
command=C:/tmp/hoge.sh
args[0]=foo
args[1]=bar
args[2]=baz
java程序读起来像:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream("resources/command.properties");
Properties prop = new Properties();
prop.load(is);
List<String> list = new ArrayList<String>();
list.add(prop.getProperty("command"));
list.add(prop.getProperty("args[0]"));
list.add(prop.getProperty("args[1]"));
list.add(prop.getProperty("args[2]"));
ProcessBuilder pb = new ProcessBuilder(list);
Process p = pb.start();
int returnValue = p.exitValue();
此程序在生产环境中的linux上运行。但是由于开发环境的管理,我们使用windows作为开发环境。
先决条件
太多了 .sh
以及 .properties
我们系统上的文件。所以我想用同样的方法 .properties
关于开发环境和生产环境的文件,或者至少我想用 .properties
用简单的字符串替换文件(在上面的例子中,我要做的只是替换 command=C:
至 command=
). 我要避免准备专门的 .properties
分别用于开发环境和生产环境的文件。
我们使用java的windows版本主要是因为两个原因:1)我们从java程序调用的中间件(它只支持windows和rhel,但不支持wsl环境),2)项目成员的技能集(只有少数成员可以流利地使用windows和linux)。
我们希望尽可能避免只在开发环境中使用的额外代码,因为代码覆盖率度量和质量管理。
我所尝试和证实的
测试java程序和 .sh
在windows环境下,我决定使用wsl2。
跑 .sh
在windows上,我设置了wsl2并修改了 .sh
文件夹。我已将以下默认值添加到键 HKEY_LOCAL_MACHINE\SOFTWARE\Classes\sh_auto_file\shell\open\command
跑 .sh
在wsl2上:
"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "$arg=\"%1\";wsl (\"/mnt/\"+[System.Char]::ToLower($arg[0])+$arg.Substring(2,$arg.Length-2) -replace '\\', '/'); exit $LASTEXITCODE"
在命令提示符下,我已确认可以运行 .sh
通过文件关联在wsl2上使用bash,并获取 .sh
适当地。
C:\tmp>hoge.sh
C:\tmp>echo %ERRORLEVEL%
5
内容 hoge.sh
是:
sleep 1
exit 5
问题
java程序运行 .sh
在linux上正确保存文件。但在windows上,它会导致如下错误:
Exception in thread "main" java.io.IOException: Cannot run program "C:/tmp/hoge.sh": CreateProcess error=193, %1 is not a valid Win32 application
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at org.example.Main.main(Main.java:16)
Caused by: java.io.IOException: CreateProcess error=193, %1 is not a valid Win32 application
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:386)
at java.lang.ProcessImpl.start(ProcessImpl.java:137)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 1 more
问题
我怎么跑 .sh
从java到wsl2上的文件关联?或者,是否没有办法根据文件关联启动程序并在java中获取返回值?
请注意,您可以通过以下方式启动具有文件关联的程序: java.awt.Desktop#open()
,但它没有获取返回值的方法。
还要注意,准备 .properties
像下面这样的开发环境的文件需要我们的先决条件非常艰苦的工作。
command=wsl
args[0]=C:/tmp/hoge.sh
args[1]=foo
args[2]=bar
args[3]=baz
1条答案
按热度按时间dgiusagp1#
您可以让windows和linux版本都运行bash-c“yourcommand”,以简化操作系统处理的差异。wsl安装bash.exe,用cmd.exe确认它在那里:
如果在两个操作系统上都正确设置了路径,则可以使用“bash”作为命令:
为了让上面的工作,尽管你需要
cmd[2]
作为一个字符串,包含用空格分隔的args[0..n]值,如果这些值也包含空格,则用引号转义,以便为脚本提供正确的参数。比如:如果你的路径没有设置,你可以调整你的启动代码来选择
bash.exe
或者/bin/bash
基于os.name
: