#java
#java
Вопрос:
Я пытаюсь запустить сценарий оболочки из java и хочу получить значение выхода из сценария оболочки на Java. Ниже приведены коды, которые я пробовал, вместе с их выводами
Java-код 1:
try {
ProcessBuilder processBuilder = new ProcessBuilder("cmd.exe", "/c", "dir //pathOfSHFile//Test.sh");
Process proc = processBuilder.start();
proc.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(proc.getInputStream()));
String line = "";
String output = "";
while ((line = in.readLine()) != null)
{
output = line;
}
System.out.println("### " output);
} catch (Throwable t) {
t.printStackTrace();
}
Test.sh файл
#!/bin/sh
echo "good"
Вывод 1:
### Volume in drive C is OSDisk Volume Serial Number is *** Directory of C:DataCode07-12-2020 12:10 22 Test.sh
Ожидал «good» в качестве результата.
Java-код 2:
try {
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(new String[]{"C:\Data\Code", ".\Test.sh"});
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line = input.readLine()) != null) {
System.out.println(line);
}
} catch (Exception e) {
System.out.println(e.toString());
e.printStackTrace();
}
Вывод 2:
java.io.IOException: Cannot run program "C:DataCode": CreateProcess error=5, Access is denied
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1048)
at java.lang.Runtime.exec(Runtime.java:621)
at java.lang.Runtime.exec(Runtime.java:486)
at Intersecttion.main(Intersecttion.java:53)
Caused by: java.io.IOException: CreateProcess error=5, Access is denied
at java.lang.ProcessImpl.create(Native Method)
at java.lang.ProcessImpl.<init>(ProcessImpl.java:444)
at java.lang.ProcessImpl.start(ProcessImpl.java:140)
at java.lang.ProcessBuilder.start(ProcessBuilder.java:1029)
... 3 more
Я пытался дать разрешение всем папкам, но результат все тот же.
Мне нужно также передать один аргумент сценарию, но я не уверен, как это сделать, а также запустить скрипт и получить значение выхода.
Есть ли лучший способ сделать это, кроме вышеперечисленных.
Комментарии:
1. Я действительно не помню, как именно это работает в Windows, но разве вы не должны запускать скрипт-бегун, например [
cmd.exe
,/c
, путь к исполняемому файлу script runner , путь к скрипту ]? (Я имею в виду, что нет аргументов с пробелами, нет пробелов между ними, как в вашем # 1,dir
встроен в cmd, Windows не знает об ошибках,C:DataCode
может быть каталогом и т. Д. И т. Д. И т. Д.)2. Да, я пытался протестировать и запустить это в Windows. Я пытаюсь поместить код в Linux и проверить, работает он или нет
3. Нет, это то, чего мне не хватало, и я думаю, что в первом выводе он просто возвращал последнюю папку, которую я упомянул, вместо запуска Test.sh досье.
4. В Java 7 добавлен метод redirectOutput для класса
ProcessBuilder
. Существует также методredirectError
. Разве это не то, что вы ищете? или, возможно, метод inheritIO подходит?
Ответ №1:
Версия 2 пытается выполнить папку. Это должно сработать:
String path = "C:\Data\Code";
String command = path "\Test.bat"; // Test.sh renamed
// String command = "bash Test.sh"; // bash execution when installed on Windows
Runtime rt = Runtime.getRuntime();
Process pr = rt.exec(command, null, new File(path));
BufferedReader input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
String line = "";
while ((line = input.readLine()) != null) {
System.out.println(line);
}
Однако вместо этого вам, возможно, придется изменить свой сценарий на командный файл «Test.bat», поскольку Windows не будет изначально выполнять сценарии оболочки. Вы также можете установить bash и выполнить bash
команду со сценарием в качестве параметра. Я добавил это как прокомментированную строку.
Комментарии:
1. OP запрашивает проблему выполнения сценария оболочки Unix (-like), а не пакетный файл Windows. Переименование файла сценария определенно не является решением, поскольку для этого требуется перенос сценария в Windows.
2. Где вы прочитали, что он должен быть Unix-подобным? echo «good» также может быть частью пакетного файла. Проблема, которую я понял здесь, заключалась в том, что все, что должно было быть выполнено, не было выполнено должным образом из Java.
3. 1) В названии вопроса четко указан сценарий «оболочки», в то время как Windows использует терминологию «пакетный файл» со времен DOS. 2) Фрагмент кода демонстрирует исходный код сценария оболочки. 3) Оба фрагмента Java пытаются выполнить
test.sh
. 4) Я не думаю, что у OP возникнет вопрос только оecho
внешнем запуске сингла.4. Тем не менее, я думаю, что проблема, отображаемая в обеих версиях выше, была вызвана не выполнением сценария оболочки, а выполнением команды в неправильном месте.
5. Я сейчас не на компьютере с Windows, но что произойдет, если не переименовывать файл, а
bash
установить его в Windows? Будет ли Windows связывать расширениеsh
файла сbash
таким, чтобы оно выполняло эту работу?