Я пытаюсь сделать небольшой интерактивный терминал в java на основе bash, и он работает нормально, но я не понимаю, почему команда [read
] требует (входных данных), прежде чем она показывает сообщение, назначенное ему.
при выполнении ./test.sh
происходит следующее:
- stdin получает
started..
и блокируется из-за [read
] команда - Если я напишу что-то еще, из-за
process != null && process.isAlive()
входные данные перейдут к stdout , и теперь stdin будет освобожден для получения what is your name?: the_inputs
и все последующие строки.
Что я делаю не так?
test. sh file
#! /bin/bash
echo "started.."
read -p "what is your name?:" var
echo "Nice to meet you: $var"
echo "ended."
Java коды
public static void main(String[] args) throws IOException, InterruptedException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(1);
Scanner scanner = new Scanner(System.in);
BS bs = new BSImpl(DEFAULT_BUFFER_SIZE, BSDefaultStdoutListener.INSTANCE);
while (bs.isRunning() && scanner.hasNextLine()) {
BSReader bsr = bs.write(scanner.nextLine());
if (bsr == null)
continue;
executor.submit(bsr);
}
scanner.close();
}
public BSReader write(String inputs) throws IOException, InterruptedException {
synchronized (lock) {
if (process != null && process.isAlive()) {
OutputStream out = process.getOutputStream();
out.write((inputs+"\n").getBytes());
out.flush();
return null;
}
this.process = _execute(inputs);
return new BSReaderImpl(listener, buffer);
}
}
private Process _execute(String inputs) throws IOException {
Process process = new ProcessBuilder().redirectErrorStream(true).command(new String[] { "bash", "-c", inputs })
.directory(workDir).start();
return process;
}
BSReaderImpl класс
public BSReaderImpl(BSListener listener, byte[] buffer) {
this.listener = listener;
this.buffer = buffer;
}
@Override
public Void call() throws Exception {
int n = -1;
String outputs = null;
while ((n = in.read(buffer, 0, buffer.length)) != -1) {
outputs = new String(buffer, 0, n);
listener.onReading(outputs);
}
return null;
}