0

I have a shell file shell.sh that echo hi every 1 second. I would like to display the real time output of my shell script on my website in a box.

However, the problem is that, my code doesn't show the output in a box. And when I click on it, everything disappears and I just see a white page.

The following is my php file.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
    <form method="GET" action="splitter.php">
        <label for="folderPath">Folder Path:</label>
        <input type="text" id="folderPath" name="folderPath">
    <br></br>
        <fieldset id="khz">
            <p>Please Choose Khz: </p>
          <input type="radio" value="8khz" name="khz"> 8khz <br>
          <input type="radio" value="16khz" name="khz"> 16khz <br>
        </fieldset>
    <br></br>
        <fieldset id="audio-type">
            <p>Please Choose Type: </p>
          <input type="radio" value="C12" name="group2"> Channel 1 & 2 <br>
          <input type="radio" value="LR" name="group2"> Left to Right <br>
        </fieldset>
        <div class="spaceh10"></div>
        <input class = "submitButton" type="submit" value="Submit">

    <div class="spaceh10"></div>
    <div style="width:500px;height:100px;border:1px solid #000;">
    <?php
    if (isset($_GET['folderPath']) && !empty($_GET['folderPath']) && 
    isset($_GET['khz']) && isset($_GET['group2'])) {

    $folderPath = $_GET['folderPath'];
    $khz = $_GET['khz'];
    $group2 = $_GET['group2'];
    #$folderPath $khz $group2
    $command = './shell.sh';
    while (@ ob_end_flush()); // end all output buffers if any

    $proc = popen($command, 'r');
    echo '<pre>';
    while (!feof($proc)){
        echo fread($proc, 4096);
        @ flush();
    }
    echo '</pre>';
    }
    ?>
    </div>
</body>
</html>

and below is my shell script

while true
do 
    echo "Hi"
    sleep 1
done

How do I make my code run in the box? And make sure the outputs just stay in the box and doesn't overflow. Why doesn't my code show the output?

I am monitoring the server address which my php file is running. And when I click submit it loads forever on a white screen and since I know it's not gonna end I stop within the browser. and I get the following error.

./shell.sh: line 6: echo: write error: Broken pipe

How can I show my real time shell output in a box? and it doesn't outflow the box border?

Yuri Burkov
  • 141
  • 10

1 Answers1

2

If you are ok with using a node tool, and not pure php, checkout websocketd and this question.

PHP is not the best choice for a realtime app, because generally php apps are short lived, but what you are asking for is along the lines of a WebSocket server. Alternatively, you could use polling to call a php endpoint that reads from a log file, if you really want to use php.

However, it is possible, just not as easy as using node (or elixir, or go, or ruby, etc.), when so many more examples for this use case exist for node.

Garrett Motzner
  • 3,021
  • 1
  • 13
  • 30
  • Creating a php endpoint that reads from a log file is a bad idea as actually two processes will use the same regular file - shell script for writing and your php endpoint for reading. The log file will be simply empty for the php endpoint when other process is writing to it. You need to change the storage. For example, Redis or MySQL or something else. – skoriy Feb 11 '21 at 11:36
  • I don't follow, @skoriy. What I mentioned should be just as possible as periodically tailing a log file, which I've done a bunch. If what you are talking about is that sometimes a stream isn't flushed immediately, then yes, that is a concern, but not a huge one. And I don't see how something like redis or mysql would be exactly better. You still have the same concern: making sure the data is flushed/finalized regularly. And for the parameters of this project, redis, etc. would be overkill, most likely. – Garrett Motzner Feb 12 '21 at 23:26
  • I tested this, and it works. I took the example shell script and put it in `echo_hi` with a shebang and made it executable. Then I ran `./echo_hi > hi.log & less +F hi.log`. `less` (could have been `tail -f`) was able to show the data as the script generated it. So I don't think you are correct, @skoriy, or I misunderstood you. – Garrett Motzner Feb 12 '21 at 23:40
  • yes, I'm incorrect when saying that it is not possible that one proc writes to a regular file and another one reads from that file. I simple tried to open a file which is being written by Vim and I just saw nothing. That was so because vim doesn't refresh file content by default. Thank you. – skoriy Feb 14 '21 at 18:13
  • Correct, because vim uses buffers. In vim you have to send the `:e` command to refresh the buffer, and the `:w` command to write to the file, or you will not see or cause any changes. – Garrett Motzner Feb 15 '21 at 20:26