1

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

Chigid
  • 11
  • 1
  • You may be looking for [server-sent events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events). – Andy Aug 02 '23 at 16:48
  • 1
    Thanks, I got it working with server-sent event – Chigid Aug 02 '23 at 19:54

0 Answers0