Невозможно получить результат команды system2 языка R

Я не могу получить результат system2. попытался выполнить образец файла jar.

execute_system.R:

workingDir <- "C:/Code"
setwd(workingDir)
command <- "java -jar sample.jar 674"
commandResult <- system2(command, stdout="C:/Code/stdout.txt", stderr="C:/Code/stderr.txt")
cat("commandResult: ", commandResult)

Я получаю сообщение об ошибке при выполнении этого файла execute_system.R и создается пустой файл (stdout.txt, stderr.txt)

commandResult: 127
warning message: running command '"java -jar sample.jar 674"' had status 127

Я хочу прочитать результат команды system2 и должен обрабатывать данные результата.

Когда я выполняю ту же командную строку, я получаю правильный результат

C:/Code>java -jar sample.jar 123
convert from String to int...
Input: 123
Value: 123
Conversion process done!!!

Фактический код Java

public class Conversion{
   public static void main(String args[]){
      System.out.println("convert from String to int...");
      String input = args[0];
      System.out.println("Input: " + input );
      int value = Integer.valueOf(input)
      System.out.println("Value: " + value);
      System.out.println("Conversion process done!!!);
   }
}

Я преобразовал эту java-программу в исполняемый файл jar (sample.jar).

Пожалуйста, помогите мне. Спасибо заранее.

Ответ 1

Используя ваш код, он работал у меня без ошибок, когда я сделал следующее:

system2('java', args = c('-jar', 'sample.jar', '123'),
         stdout = 'stdout.txt', stderr = 'stderr.txt')

Я запускал это на Mac OSX 10.10.5 (Yosemite). Результаты были напечатаны на "stdout.txt".

Как видно из документации для system2, первая опция - это просто команда (т.е. никаких аргументов). Аргументы должны быть указаны с параметром args.

Вот фрагмент из раздела Подробнее:

Подробнее

В отличие от системы, команда всегда цитируется shQuote, поэтому она должна быть единой командой без аргументов.

...

Ответ 2

Это легко сделать ошибку.

Во-первых, давайте определим некоторые термины:

  • Заявление Это кусок кода оболочки, который обычно представляет собой одно действие для оболочки для выполнения. Действие может быть документированной встроенной оболочкой или командой с ключевыми словами плюс аргументы, именем файла внешнего исполняемого файла с аргументами плюс, составной командой (такой как фигурный блок или подоболочка), конвейером всего вышеперечисленного или списком команд все вышеперечисленное. Несколько операторов обычно могут быть закодированы последовательно с использованием разделителей операторов, которые различаются в зависимости от оболочки. Например, оболочка Unix bash использует точки с запятой (для выполнения на переднем плане) или амперсанды (для фона), а оболочка Windows cmd использует амперсанды (для переднего плана).
  • команда Это очень общий термин, который может относиться к любому из вышеперечисленных типов команд, или к целому оператору, или даже к нескольким последовательным операторам. Это тот термин, который требует контекста, чтобы уточнить его значение.
  • простая команда Это команда, которая выполняет только встроенную оболочку или внешний исполняемый файл. Это может происходить как их собственные операторы или они могут составлять часть составных команд, конвейеров или списков команд. В оболочке bash присваивание и перенаправление переменных могут быть частью или даже всей простой командой.
  • командное слово В контексте одной простой команды это имя программы, которую вы хотите запустить. Это будет либо документированное имя встроенной оболочки, либо имя внешнего исполняемого файла. Это иногда описывается как первое слово команды или нулевой аргумент.
  • Аргументы команды В контексте одной простой команды это ноль или более (дополнительных) аргументов, передаваемых встроенному или исполняемому файлу.
  • Командная строка Этот термин несет в себе предположение, что он относится к одной строке кода оболочки. Тем не менее, он часто используется несколько более свободно, чтобы описать любой автономный, часто одноразовый фрагмент кода оболочки, который в действительности может содержать разрывы строк, и, таким образом, технически состоит из более чем одной текстовой строки. Термин команда иногда используется как сокращение для этой концепции, что еще больше увеличивает ее двусмысленность. Также обратите внимание, что командная строка иногда используется как сокращение для типа интерфейса командной строки пользовательского интерфейса, который никогда не связывается с неквалифицированным термином команда.
  • системная команда Это еще один общий термин, который требует контекста, чтобы уточнить его значение. Это можно считать синонимом команды, за исключением того, что дополнительный модификатор "система" предполагает, что выполнение команды инициируется из программного контекста, существующего вне оболочки, такого как R-сеанс.

Конструкция функции system2() видимому, предполагает, что авторы только предполагали, что она будет использоваться для запуска простых команд. Он принимает командное слово в качестве первого аргумента функции (ожидается, что это скалярная строка, что означает символьный вектор из одного элемента), а командные аргументы - в качестве второго (также ожидается, что это будет символьный вектор, ноль или более элементов). Вот как документация описывает это в описании этих двух аргументов функции:

command

системная команда, которая будет вызвана, как строка символов.

args

символьный вектор аргументов для command.

Вышесказанное не дает полной ясности, но первое предложение раздела "Подробности" помогает:

В отличие от system(), command всегда shQuote() кавычки shQuote(), поэтому она должна быть единственной командой без аргументов.

Как вы можете видеть, документация немного расплывчата в том смысле, что она содержит общий термин команда без особых пояснений. Они также используют расплывчатую системную команду термина, которая также мало помогает. Они означают, что первая command аргумента функции предназначена для того, чтобы быть командным словом простой команды. Если вы хотите передать какие-либо аргументы команды, вы должны указать их во втором аргументе args функции.

В защиту авторов, код оболочки может быть очень зависимым от платформы и несовместимым в реализации и поведении. Использование более точных терминов, которые я определил в этом посте, подвергло бы авторов документации риску совершения ошибок, по крайней мере, в отношении некоторых систем, которые R стремится поддерживать. Неопределенность может быть защитой от риска прямой ошибки.

Обратите внимание, что это отличается от других системных командных функций R, system():

command

системная команда, которая будет вызвана, как строка символов.

А в разделе Подробности:

command анализируется как команда плюс аргументы, разделенные пробелами. Поэтому, если путь к команде (или один аргумент, такой как путь к файлу) содержит пробелы, он должен быть shQuote() кавычки, например, shQuote(). Unix-подобные программы передают командную строку в оболочку (обычно это /bin/sh, а POSIX требует эту оболочку), поэтому command может быть чем угодно, что оболочка считает исполняемым, включая сценарии оболочки, и может содержать несколько команд, разделенных ; ,

Поэтому для system() первая command аргумента функции - это полная командная строка.

Таким образом, они фактически используют одно и то же имя аргумента функции (command) и описание ("системная команда, которая должна быть вызвана как строка символов."), Даже если аргумент имеет два совершенно разных значения между system() и system2() ! Понимание этой документации действительно требует тщательного анализа читателем.


Итак, наконец, мы можем понять, как правильно использовать system2() для вызова желаемой команды Java:

word <- 'java';
args <- c('-jar','sample.jar','674');
result <- system2(word,args,stdout='C:/Code/stdout.txt',stderr='C:/Code/stderr.txt');

Просто чтобы попытаться прояснить это, полезно поэкспериментировать с поведением этих функций, попробовав несколько простых тестовых случаев. Например (на моей оболочке Cygwin Bash):

system('printf %d:%x\\\\n 31 31');
## 31:1f
system2('printf',c('%d:%x\\\\n','31','31'));
## 31:1f

(Обратите внимание, что четырехкратная обратная косая черта необходима, потому что они проходят через 3 контекста интерполяции, а именно: (1) буквенная интерполяция R-строки, (2) лексический контекст bash (не в одинарных кавычках) и (3) интерполяция команды printf его первый аргумент команды. Нам нужно printf для интерполяции финального кода символа \n ASCII.)

Кроме того, следует отметить, что, хотя system2() явно поощряет запуск только простых команд путем принудительного разделения командного слова и командных аргументов на отдельные функциональные аргументы, очень возможно подорвать это намерение и использовать метасимволы оболочки для выполнения некоторых явно не -простой код оболочки через интерфейс system2():

system('echo a b; echo c d');
## a b
## c d
system2('echo',c('a','b; echo c d'));
## a b
## c d

Это, конечно, крайне нежелательно.