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?

7
  • By "realtime" do you mean "live updating" or "current state when page loaded"? Commented May 7, 2020 at 21:23
  • @GarrettMotzner Live updating! outputs are spit out in real time live updating. Commented May 7, 2020 at 21:37
  • Ok, well. then, PHP is probably a bad choice, because you want websockets, and while PHP can do websockets, it isn't a natural fit. Node is probably the easiest option. Commented May 7, 2020 at 22:01
  • Alternatively, you could do polling, basically reading a log file every few seconds and displaying that content to the page, but websockets fit your use case better. Commented May 7, 2020 at 22:03
  • Node example that does what you want: github.com/joewalnes/websocketd Commented May 7, 2020 at 22:04

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
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.
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.
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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.