英文:
Application running using os.exec doesn't load java libraries properly
问题
我很乐意帮助你。我正在将一个简单的Minecraft启动器从Java重写为Go。一切都很好,只有一个问题。
我有一个使用os.Exec执行的start函数,执行以下命令:
java -Xincgc -Xmx1024M -Djava.library.path="/minecraft/bin/natives/" -cp "/minecraft/bin/*" -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true net.minecraft.launchwrapper.Launch --username user --session session --version 1.6.4 --gameDir "/minecraft" --assetsDir "/minecraft" --tweakClass cpw.mods.fml.common.launcher.FMLTweaker
通过bash或cmd运行这个命令一切正常,但是当使用Go函数执行时,返回以下内容:
Could not find or load main class net.minecraft.launchwrapper.Launch
我认为os.exec(Command)无法正确解释命令的这一部分:
-cp "/minecraft/bin/*"
可能是因为我使用了strconv.Quote()函数引用了字符串"/minecraft/bin/*",或者是因为星号的原因。我真的不知道发生了什么。顺便说一下,os.exec运行的命令是正确的(我使用fmt将其输出到stdout进行调试)。
程序:
func start(login string, session string, ram string) {
//启动游戏
app := "java"
arg0 := "-Xincgc"
arg1 := "-Xmx" + ram + "M"
arg2 := "-Djava.library.path=" + strconv.Quote(filepath.FromSlash(client+"bin/natives/"))
arg3 := "-cp"
arg4 := strconv.Quote(filepath.FromSlash(client + "bin/*"))
arg5 := "-Dfml.ignoreInvalidMinecraftCertificates=true"
arg6 := "-Dfml.ignorePatchDiscrepancies=true"
arg7 := "net.minecraft.launchwrapper.Launch"
arg8 := "--username"
//arg9是login
arg10 := "--session"
//arg11是session
arg12 := "--version 1.6.4"
arg13 := "--gameDir"
arg14 := strconv.Quote(filepath.FromSlash(client))
arg15 := "--assetsDir"
arg16 := strconv.Quote(filepath.FromSlash(client + "assets"))
arg17 := "--tweakClass cpw.mods.fml.common.launcher.FMLTweaker"
cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
fmt.Println(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
}
英文:
I would really appreciate if you helped me. I'm rewriting a simple Minecraft launcher from Java to Go. Everything is good, in exception of one thing.
I have a start function which executes using os.Exec this command:
java -Xincgc -Xmx1024M -Djava.library.path="/minecraft/bin/natives/" -cp "/minecraft/bin/*" -Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true net.minecraft.launchwrapper.Launch --username user --session session --version 1.6.4 --gameDir "/minecraft" --assetsDir "/minecraft" --tweakClass cpw.mods.fml.common.launcher.FMLTweaker
Everything is fine running this through bash or cmd, but when executed with Go function it returns the following:
Could not find or load main class net.minecraft.launchwrapper.Launch
I think os.exec(Command) cannot properly interpet this part of command:
-cp "/minecraft/bin/*"
Maybe that's because I quoted string "/minecraft/bin/*" with strconv.Quote() function or because of asterisk. I really don't know what's heppening. Ah, btw, the command os.exec has run is correct, though (I read it in stdout with fmt for debugging purposes).
program:
func start(login string, session string, ram string) {
//start game
app := "java"
arg0 := "-Xincgc"
arg1 := "-Xmx" + ram + "M"
arg2 := "-Djava.library.path=" + strconv.Quote(filepath.FromSlash(client+"bin/natives/"))
arg3 := "-cp"
arg4 := strconv.Quote(filepath.FromSlash(client + "bin/*"))
arg5 := "-Dfml.ignoreInvalidMinecraftCertificates=true"
arg6 := "-Dfml.ignorePatchDiscrepancies=true"
arg7 := "net.minecraft.launchwrapper.Launch"
arg8 := "--username"
//arg9 is login
arg10 := "--session"
//arg11 is session
arg12 := "--version 1.6.4"
arg13 := "--gameDir"
arg14 := strconv.Quote(filepath.FromSlash(client))
arg15 := "--assetsDir"
arg16 := strconv.Quote(filepath.FromSlash(client + "assets"))
arg17 := "--tweakClass cpw.mods.fml.common.launcher.FMLTweaker"
cmd := exec.Command(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
cmd.Run()
fmt.Println(app, arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, login, arg10, session, arg12, arg13, arg14, arg15, arg16, arg17)
}
答案1
得分: 1
“正确传递参数给Go Exec”这个问题提到:
如果参数中有空格,exec.Command(...)
会在参数周围添加双引号,所以你只需要在需要的地方转义\"
。
在你的情况下,-cp "/minecraft/bin/*"
会作为两个独立的参数传递给exec.Command
。
如果你需要在一个参数中使用引号,你可以使用string literal来保留它们(正如在“How do you add spaces to exec.command in golang”中所评论的)。
但是,如果在你的情况下,你需要shell来展开cp
(classpath)(如“double quotes escaping in golang exec”中所提到的),那么去掉引号:
exec.Command(..., "-cp", `/minecraft/bin/*`, ...)
英文:
The question "Properly pass arguments to Go Exec" mentions:
> exec.Command(...)
adds double quotes to the parameters if there is spaces in them, so you only need to escape \"
where you need them.
In your case, -cp "/minecraft/bin/*"
would be passed to exec.Command
as two separate parameters.
If you need quotes within one parameter, you could use a string literal to keep them (as commented in "How do you add spaces to exec.command in golang").
But if, in your case, you need the cp
(classpath) to be expended by the shell (as mentioned in "double quotes escaping in golang exec"), then remove the quotes:
exec.Command(..., "-cp", `/minecraft/bin/*`, ...)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论