【问题标题】:Java String execution in Linux terminalLinux 终端中的 Java 字符串执行
【发布时间】:2013-02-27 04:28:51
【问题描述】:

我正在使用 StringBuilder 创建一个字符串,然后尝试在 Linux 终端上执行该字符串。但不是执行整个命令,而是执行一半命令然后终止它。这是我的java代码sn-p:

moteCommand.append("CFLAGS+=-DCC2420_DEF_CHANNEL=1");
moteCommand.append(" ");
moteCommand.append("make telosb install.");
moteCommand.append(moteIdList.get(i).toString());
moteCommand.append(" bsl,");
moteCommand.append(moteAddrList.get(i).toString());
String moteCommand2 = moteCommand.toString();
Process moteProgProcess = Runtime.getRuntime().exec(moteCommand2, null,"/opt/tinyos-2.x/apps/XXX/);

它给了我这个错误: 无法运行程序“CFLAGS+=-DCC2420_DEF_CHANNEL=1”(在目录“/opt/tinyos-2.x/apps/xxx”中):java.io.IOException: error=2, No such file or directory

我不明白为什么系统进程试图只执行一半的字符串。如果有人知道原因,请告诉我。

谢谢。

【问题讨论】:

    标签: java system exec processbuilder


    【解决方案1】:

    当您调用Runtime.exec() 时,直到第一个空格的字符必须是您要启动的程序的名称。之后,空格之间的每个“部分”都是一个单独的参数。请注意,调用 Runtime.exec() 与在 bash(或任何其他 shell ...)中键入命令并按 Enter 完全不同!如果您键入在 bash 中可以正常工作的命令,并不意味着它可以与 Runtime.exec() 一起使用。例如,shell 命令(不是外部程序)在Runtime.exec() 中不起作用。

    你应该做的是使用ProcessBuilder

    实例化它,操纵它的Map,它代表环境选项(即,您在命令名称之前传递的东西,例如cflags,以及您可能想要的任何其他东西),设置命令名称,一次给一个参数(参数不会在空格处分割,因此您可以传递包含空格的路径,例如)等。您可以以多种不同的方式操作标准输入、标准输出和标准错误(例如:使用与 Java 进程使用的相同;或获取 InputStream 和 OutputStream 的实例以向进程写入和读取;或管道它们),然后运行进程。

    类似的东西:

    final ProcessBuilder pb = new ProcessBuilder("make", "telosb", "install" blablablabla);
    final Map<String, String> env = pb.environment();
    env.put("CFLAGS", "....your options....");
    pb.start(); // take the Process instance, and you will be able to read the output, wait for it to finish, get the exit code, etc 
    

    【讨论】:

    • 你能给我举个关于我的代码的例子吗?因为我已经尝试过像这样使用 ProcessBuilder 并且它不起作用。 ProcessBuilder pb = new ProcessBuilder("CFLAGS+=-DCC2420_DEF_CHANNEL=1", "make", "telosb", "install.0", "bsl,/dev/ttyUSB0"); moteProgProcess = pb.start();
    • 你没有做我上面描述的事情,这就是它不起作用的原因。实际上,您使用它的方式与使用Runtime.exec() 完全相同。打开 ProcessBuilder 的 JavaDocs,您会得到一个很好的示例,其中包含环境选项以及所有内容:docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html
    • 请注意,您的“myCommand”不是CFLAGS.....,而是make,即您要启动的进程的名称。你CFLAGS... 是环境的一部分。
    • 这是你要我做的吗? ProcessBuilder pb = new ProcessBuilder("make", "telosb","install.0","bsl,/dev/ttyUSB0");Map env = pb.environment(); env.put("var1","CFLAGS+=-DCC2420_DEF_CHANNEL=1");pb.directory(new File("/opt/tinyos-2.x/apps/XXX"));进程 p1 = pb.start(); ??
    • 没有。您将值“CFLAGS+=-...”放在名为“var1”的变量上。你需要的是一个名为 CFLAGS 的变量。
    猜你喜欢
    • 2012-01-30
    • 1970-01-01
    • 1970-01-01
    • 2015-08-16
    • 2011-05-09
    • 2018-12-28
    • 2012-03-06
    • 2014-07-03
    • 2015-11-27
    相关资源
    最近更新 更多