25

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

sh -l -c "./foo"

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

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

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

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

有没有办法将特定于平台的 EOF 插入到 Java 字符串中?还是我应该寻找另一种方法,例如在调用 "sh" 之前写入临时脚本?

4

6 回答 6

52

用这个:

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

要点:不要放双引号。这仅在在shell中编写命令行时使用!

例如,echo "Hello, world!"(在 shell 中输入)被翻译成:

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

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

于 2008-10-02T11:54:21.960 回答
10

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

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

在 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)

或者更好,java.lang.ProcessBuilder.

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

Runtime.getRuntime().exec(new String[] {
    "sh", "-c", "sh -l -c \"echo foo; echo bar;\""
});
于 2008-10-02T14:26:14.793 回答
4

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

于 2008-10-02T11:45:02.357 回答
0

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

于 2008-10-02T11:47:06.517 回答
0

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

例如

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

于 2008-10-02T12:05:34.583 回答
0

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

于 2008-10-02T14:48:29.780 回答