Вызов внешнего процесса из Groovy/Java дает неожиданный результат

#java #groovy #process #external

Вопрос:

Из Groovy/Java я пытаюсь выполнить следующую команду: cmd /c echo mytext .

 import java.nio.charset.Charset

println(Charset.defaultCharset().displayName()) //returns windows-1250
//in console chcp returns 852

def arg = "/c echo mytext"
def pb = new ProcessBuilder("cmd", arg)
def proc = pb.start()

def stdInput = new BufferedReader(new InputStreamReader(proc.getInputStream(), "CP852"))
def stdError = new BufferedReader(new InputStreamReader(proc.getErrorStream(), "CP852"))

def line = null
println("Here is the standard output of: cmd "   arg)
while ((line = stdInput.readLine()) != null) {
    println(line)
}

println("Here is the standard error of the command (if any):")
while ((line = stdError.readLine()) != null) {
    println(line)
}
 

Заводной: 2.4.21, 3.0.9

Java: zulu11.50.19-ca-fx-jdk11.0.12-win_x64

Результатом является mytext" (включая окончание двойной кавычки). Я не могу понять, почему существует двойной вопрос. Кто — нибудь может помочь мне объяснить, почему он там?

Спасибо.

Комментарии:

1. ProcessBuilder("cmd", "/c", "echo", "mytext") должно помочь.

2. @daggett Спасибо, это работает. Так просто и не приходило мне в голову. И я все еще любопытствую по поводу причины двойного вопроса. Вы знаете, почему он там?

3. «И я все еще любопытствую по поводу причины двойного коута. Ты знаешь, почему он там?» — В коде ProcessBuilder("cmd", "/c", "echo", "mytext") вы можете заменить двойные кавычки одинарными кавычками и вести себя точно так же.

Ответ №1:

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

итак, ProcessBuilder("cmd", "/c echo mytext") на самом деле работает cmd "/c echo mytext"

попробуйте выполнить эту команду в командной строке:

 c:> cmd "/c echo mytext"
mytext"
 

^^^ это именно то, что у вас есть в результате

вопрос, почему cmd интерпретирует аргументы таким образом, должен быть адресован microsoft — возможно, есть логическое объяснение

однако echo не анализирует аргументы и выводит строку аргументов как есть

 c:> echo "my text"
"my text"

c:> echo my text
my text
 

означает, что правильный ответ для echo my text : ProcessBuilder("cmd", "/c", "echo my text")


позвольте мне предложить отличный вариант для вашего кода:

 def out = {s-> print(s)} as Appendable
def err = {s-> print(s)} as Appendable

def command = ['cmd', '/c', 'echo my text']
def proc = command.execute()

proc.waitForProcessOutput(out,err)