#java #linux #bash
#java #linux #bash
Вопрос:
Моя цель — выполнить персонализированное приглашение в оболочке bash в Linux и выполнить заказы. Результат должен быть таким, как на изображении.
Итак, я полагаю, я должен начать с чего-то вроде:
ProcessBuilder builder = new ProcessBuilder();
builder.command("sh");
builder.directory(new File(System.getProperty("user.home")));
Process process = builder.start();
или
String homeDirectory = System.getProperty("user.home");
Process process;
try {
System.out.print("# MyShell> ");
process = Runtime.getRuntime().exec(String.format("sh", homeDirectory));
} catch (IOException e) {
System.err.println("Error en el método exec()");
e.printStackTrace();
}
Управление исключениями.
В основном это запуск персонализированной функциональной командной строки bash на Java и управление сообщениями об ошибках (например, изменение его цвета). Также управление выходом с помощью персонализированного слова, например ‘quit’ вместо ‘exit’.
Примечание: я не пытаюсь выполнить скрипт или некоторые команды, такие как ‘tree’ или ‘ls’, как во многих других примерах здесь. Я ищу способ запустить свой персонализированный bash и делать все, что позволяет мне система в bash или близко к этой идее.
Комментарии:
1. Что произошло, когда вы попробовали свои собственные предложения?
2. Почему вы хотите это сделать? Java предназначена для работы на всех ОС, поэтому в основном у них нет bash, и они будут аварийно завершены или будут иметь приличное сообщение об ошибке. Зачем использовать java для доступа к bash?
3. Что произошло, когда вы попробовали свои собственные предложения? Я не мог заставить это работать.
4. Я не хочу запускать программу в Windows или Mac, просто попробуйте это в Linux.
5. Вы сказали, почему этот другой вопрос не то, что вы хотите. Когда люди спрашивали, что не так с опубликованным вами кодом, вы только говорили: «Я не смог заставить его работать», «он работает не так, как я ожидал», «он не делает то, что я пытаюсь сделать». Я уверен, что это очевидно для вас, но другие люди не могут видеть ваш экран. Представьте, что вы идете к врачу и говорите «это не работает» вместо «я не вижу левым глазом».
Ответ №1:
Эта проблема сложнее, чем кажется, из-за взаимодействия оболочки, терминала и вашей программы.
Учитывая, что требования:
- Пользовательская подсказка оболочки
- Пользовательские команды
- Пусть оболочка работает нормально
- Перехватывать вывод программы
Мое предложение:
- Выполните настройки со стороны оболочки
- Создайте pty, чтобы обмануть программы, думая, что они пишут на терминал. В Java на Linux / Mac простой способ сделать это — с помощью
script
инструмента.
Вот пример файла конфигурации оболочки myrc
:
export PS1='# MyShell> '
quit() { exit "$@"; }
и вот Shell.java
, чтобы запустить пользовательскую оболочку:
import java.io.*;
import java.nio.charset.*;
import java.lang.ProcessBuilder.Redirect;
class Shell {
public static void main(String[] args) throws IOException {
ProcessBuilder builder = new ProcessBuilder(
// Use 'script' to fool programs into thinking stdout is a tty.
"script", "-q", "/dev/null",
// Run bash with prompt and command customizations
"bash", "--rcfile", "myrc"
);
builder
// Get input from the current TTY
.redirectInput(Redirect.INHERIT)
// But pipe stdout/stderr to intercept it
.redirectErrorStream(true)
.redirectOutput(Redirect.PIPE);
Process proc = builder.start();
InputStream input = proc.getInputStream();
byte[] buffer = new byte[65536];
int read;
String search = "world";
while((read = input.read(buffer, 0, buffer.length)) != -1) {
// Simplify by assuming we only get text data, and only
// in buffers large enough to contain the entire search string
String s = new String(buffer, 0, read, StandardCharsets.UTF_8);
// Replace search word with a highlighted/colored string.
s = s.replaceAll(search, "u001B[35m<<$0>>u001B[m");
System.out.print(s);
}
System.out.println("Java program is exiting...");
}
}
Пример сеанса, показывающий пользовательскую подсказку, перехват рабочего текста (делая слово «мир» фиолетовым и окруженным угловыми скобками) и, наконец, пользовательскую quit
команду:
$ javac Shell.java amp;amp; java Shell
# MyShell> echo "hello world"
hello <<world>>
# MyShell> quit
exit
Java program is exiting...
$
Комментарии:
1. Прежде всего, спасибо за вашу помощь. К сожалению, я не могу проверить код, так как получаю эту ошибку: script: нераспознанная опция ‘—rcfile’ Я проверил в Google параметры bash, и все должно быть хорошо, но я не знаю, почему программа продолжает выдавать мне эту ошибку.
2. Я тестировал это на macOS
script
. Судя по чтению справочной страницы Linux, похоже, что так и должно быть"script", "-c", "bash --rcfile myrc", "/dev/null"
, хотя я не могу ее протестировать3. Да, это идеально. Большое вам спасибо. Теперь я собираюсь изучить код, чтобы понять, как это работает. Мне не нравится просто копировать / вставлять 😉