Can not get messages sent from bash to browser
Dear All
I am new to this forum and completely new to javascript and html programming. I thought I have simple case, but I stuck with is
So, I have a simple C++ script, which outputs on screen some counter
#include <iostream>
#include <thread>
#include <unistd.h>
int main() {
int counter = 0;
int iterations = 10000;
for (int i = 0; i < iterations; ++i) {
counter += 10;
// Use std::cerr to output the counter value directly to the terminal (unbuffered)
std::cerr << "Counter value is " << counter << " Frequency is " << counter / 10 << std::flush <<std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(100)); // Add a delay of 100 milliseconds between iterations
}
return 0;
}
Then I am running it using bash script
#!/bin/bash
# Run your C++ program and capture its output in real-time
./a.out 2>&1 | while IFS= read -r counter_value; do
counts=$counter_value
echo "Counter value is:" $counts
# You can perform additional operations with each counter_value here
done
This runs and prints on screen same as c++ code does.
I would like to have output of bash script to have printed in browser, so I made up simple nodejs server
const http = require('http');
const { exec } = require('child_process');
const fs = require('fs');
const path = require('path');
const server = http.createServer((req, res) => {
if (req.url === '/') {
// Serve the index.html file
const indexPath = path.join(__dirname, 'public', 'index.html');
fs.readFile(indexPath, 'utf8', (err, content) => {
if (err) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Error reading index.html');
return;
}
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end(content);
});
} else if (req.url === '/get_output') {
// Execute the Bash script
exec('./dispcount.sh', (error, stdout, stderr) => {
if (error) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end(`Error executing the script: ${error.message}`);
return;
}
// Send the output as the HTTP response
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end(stdout);
});
} else {
// Handle other requests (if any)
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Not found');
}
});
const port = 3000; // Change this to the desired port number
server.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
and index.html, which sits in public directory
<!DOCTYPE html>
<html>
<head>
<title>Bash Script Output</title>
</head>
<body>
<h1>Bash Script Output:</h1>
<pre id="output">Click "Start" to begin...</pre>
<button id="startButton">Start</button>
<script>
document.getElementById('startButton').addEventListener('click', () => {
// Function to update the output with new lines
function updateOutput(newOutput) {
const outputElement = document.getElementById('output');
outputElement.textContent = newOutput;
}
// Function to fetch the script output and update the page
function fetchOutput() {
fetch('/get_output').then((response) => response.text()).then((output) => {
updateOutput(output);
// Check if the output contains a number to continue updating
const lastNumber = output.match(/\d+$/);
if (lastNumber) {
// Update the output every 1 second (adjust the interval as needed)
setTimeout(fetchOutput, 1000);
}
});
}
// Call the fetchOutput function when the "Start" button is clicked
fetchOutput();
});
</script>
</body>
</html>
When page is loaded, it shows start button and some text, when I hit start, shell script is triggered, it starts a.out executable and .... nothing happens on browser screen until executable stopped (by itself or killed). Then on browser screen whole bunch of messages appear
Ideally I want to have every message printed on browser screen immediately it is spit out from bash script and formatted like
cout<<"\r" << .... <<flush
In one line, to show some sort of progress of counters. Could someone direct me how to proceed and do this? Sorry for long message, it my first message.
And thanks in advance