java 在 getRuntime().exec 中使用引号

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/161859/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 11:14:44  来源:igfitidea点击:

Using Quotes within getRuntime().exec

javaexecruntime.exec

提问by Daniel

I'd like to invoke bash using a string as input. Something like:

我想使用字符串作为输入来调用 bash。就像是:

sh -l -c "./foo"

I'd like to do this from Java. Unfortunately, when I try to invoke the command using getRuntime().exec, I get the following error:

我想从 Java 中做到这一点。不幸的是,当我尝试使用 调用命令时getRuntime().exec,出现以下错误:

      foo": -c: line 0: unexpected EOF while looking for matching `"'

      foo": -c: line 1: syntax error: unexpected end of file

It seems to be related to my string not being terminated with an EOF.

这似乎与我的字符串没有以 EOF 终止有关。

Is there a way to insert a platform specific EOF into a Java string? Or should I be looking for another approach, like writing to a temp script before invoking "sh" ?

有没有办法将特定于平台的 EOF 插入 Java 字符串?或者我应该寻找另一种方法,比如在调用“sh”之前写入临时脚本?

回答by Chris Jester-Young

Use this:

用这个:

Runtime.getRuntime().exec(new String[] {"sh", "-l", "-c", "./foo"});

Main point: don't put the double quotes in. That's only used when writing a command-line in the shell!

要点:不要加双引号。只有在shell中编写命令行时才会用到!

e.g., echo "Hello, world!"(as typed in the shell) gets translated to:

例如,echo "Hello, world!"(在 shell 中输入)被转换为:

Runtime.getRuntime().exec(new String[] {"echo", "Hello, world!"});

(Just forget for the moment that the shell normally has a builtin for echo, and is calling /bin/echoinstead. :-))

(暂时忘记shell通常有一个内置的 for echo/bin/echo而是调用。:-))

回答by Tom Hawtin - tackline

Windows command lines behave differently from UNIX, Mac OS X and GNU/Linux.

Windows 命令行的行为与 UNIX、Mac OS X 和 GNU/Linux 不同。

On Windows the process receives the input text verbatim after the executable name (and space). It's then up to the program to parse the command line (which is usually done implicitly, the programmer is often clueless about the process).

在 Windows 上,进程在可执行文件名称(和空格)之后逐字接收输入文本。然后由程序来解析命令行(这通常是隐式完成的,程序员通常对这个过程一无所知)。

In GNU/Linux the shell processes the command line, guaranteeing the familiar array of strings passed to C's mainfunction. You don't have that shell. The best approach (even on Windows) is to use one of the form of exec where you pass each command line argument individually in its own String.

在 GNU/Linux 中,shell 处理命令行,保证传递给 Cmain函数的熟悉的字符串数组。你没有那个壳。最好的方法(即使在 Windows 上)是使用 exec 的形式之一,您可以在其中单独传递每个命令行参数String

Process exec?(String[] cmdarray)    
Process exec?(String[] cmdarray, String[] envp)     
Process exec?(String[] cmdarray, String[] envp, File dir)

Or better, java.lang.ProcessBuilder.

或者更好,java.lang.ProcessBuilder

You can get a shell to do the parsing for you if you really want. This would make your example look something like (untested):

如果你真的想要,你可以得到一个 shell 来为你解析。这将使您的示例看起来像(未经测试):

Runtime.getRuntime().exec(new String[] {
    "sh", "-c", "sh -l -c \"echo foo; echo bar;\""
});

回答by Lev

EOF is NOT a character, so there's no way to write an EOF. You've forgotten to close a quoted string.

EOF 不是字符,因此无法编写 EOF。您忘记关闭带引号的字符串。

回答by Lev

The cause for this error is most likely a missing syntax token that bash expects but the string you pass ends before bash encountered it. Look for ifs, fors etc. that have no closing fi or done.

此错误的原因很可能是缺少 bash 期望的语法标记,但您传递的字符串在 bash 遇到它之前就结束了。寻找没有关闭 fi 或 done 的 ifs、fors 等。

回答by diciu

Quotes need to be escaped when inside a string. Instead of writing " write \".

引号在字符串中需要转义。而不是写“写\”。

E.g.

例如

strcpy(c, "This is a string \"with\" quotes");

strcpy(c, "这是一个字符串\"带\"引号");

回答by anjanb

if I were you, I would write the contents of the string to a temp bashfile and see if bash executes that without any error. If that executes without an error, then I would consider debugging further;

如果我是你,我会将字符串的内容写入临时 bashfile 并查看 bash 是否执行该文件而没有任何错误。如果执行没有错误,那么我会考虑进一步调试;