2013-02-27 2 views
0

Я использую StringBuilder для создания строки, а затем пытаюсь выполнить строку на терминале Linux. Но вместо выполнения всей команды он выполняет половину команды, а затем завершает ее. Это моя ява фрагмент кода:Выполнение Java-строки в терминале Linux

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, Нет такого файла или каталога

Я не понимаю, почему системный процесс пытается выполнить только половину строки. Пожалуйста, дайте мне знать, если кто-нибудь знает причину.

Спасибо.

ответ

3

Когда вы вызываете Runtime.exec(), символы до первого места должны быть именем программы, которую вы хотите запустить. После этого каждая «часть» между пробелами является отдельным аргументом. Обратите внимание, что вызов Runtime.exec() полностью отличается от ввода команды в bash (или любой другой оболочки ...) и нажатия клавиши enter! Если вы наберете команду, которая отлично работает в bash, это не значит, что она будет работать с Runtime.exec(). Например, команды оболочки (которые не являются внешними программами) не будут работать в Runtime.exec().

Что вы должны сделать, это использовать ProcessBuilder.

Инстанцировать его, манипулировать его Map, который представляет параметры окружающей среды (то есть вещи, которые вы проезжаете перед тем имя команды, такие как CFLAGS и все, что вы могли бы хотеть), установить имя команды, дать аргументы по одному (аргументы не будут разделены на пробелы, поэтому вы можете, например, передавать пути, содержащие пробелы) и т. д. Вы можете управлять stdin, stdout и stderr разными способами (например: использовать одинаковые как те, которые используются процессом 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 
+0

Не могли бы вы дать мне пример относительно моего кода? Поскольку я уже пытался использовать ProcessBuilder, как это, и он не работал. ProcessBuilder pb = new ProcessBuilder («CFLAGS + = - DCC2420_DEF_CHANNEL = 1», «make», «telosb», «install.0», «bsl,/dev/ttyUSB0»); moteProgProcess = pb.start(); –

+1

Вы не делаете то, что я описал выше, поэтому он не работает. Фактически, вы используете его точно так же, как вы используете 'Runtime.exec()'. Откройте JavaDocs для ProcessBuilder, и вы получите хороший пример с параметрами среды и всеми: http://docs.oracle.com/javase/7/docs/api/java/lang/ProcessBuilder.html –

+0

Обратите внимание, что ваш «myCommand» «не является« CFLAGS ..... », но это« make », то есть имя процесса, который вы хотите запустить. Вы 'CFLAGS ...' вещь является частью среды. –

Смежные вопросы