PHP running a Bash Script Works, Except Won't Mkdir

www-data is the user running the PHP script which is executed from an HTML button which passes several variables to the PHP script successfully.

The PHP script then passes those variables to a bash script successfully.

The issue comes when the bash script tries to make a directory in /media/bh/STORAGE/V/ folder. That folder is owned by www-data and has executable permissions.

If I comment out the mkdir line, all works fine and the expected output is sent back to my PHP script. But if I leave the mkdir comment, it throws an error.

Thanks for any assistance if the issue seems obvious enough to somebody willing to share their thoughts.

Bash Script code:

!/usr/bin/bash
echo "Here we go!"
echo "PHP Path: $PATH"
echo "Image Path: $1"
echo "Seed: $2"
echo "Prompt: $3"
echo "Batch Size: $4"
echo "Output Filename: $5"

mkdir /media/bh/STORAGE/V/test/
# the above mkdir will only work if I run the script as user
# ie www-data executing this script through PHP throws an error at the mkdir part
# despite www-data being the owner of /media/bh/STORAGE/V/ and having execute priv

My PHP code:

<?php

if($_SERVER['REQUEST_METHOD'] === 'POST') {

$image_path = '/media/bh/STORAGE/V/example.png';

$seed = rand(); // Generate a random seed instead of using a hardcoded one

$prompt = "a pixar cartoon man flies through the air with a smiling sun above him";

$batch_size = 5;

$output_filename = "/media/bh/STORAGE/V/Temp/example.png";

// Create an array of arguments to pass to exec()

$args = [

'./I2T2I.sh',

$image_path,

$seed,

$prompt,

$batch_size,

$output_filename

];

// Use escapeshellarg on all arguments to ensure they're safe for shell execution

$escapedArgs = array_map('escapeshellarg', $args);

echo "Running command: <br><br>" . implode(' ', $escapedArgs);

// Use exec() instead of shell_exec(), which allows you to get the output and return code

$output = [];

$return_var = 0;

exec(implode(' ', $escapedArgs), $output, $return_var);

if ($return_var !== 0) {

// There was an error running the command

$error = error_get_last();

echo "<br><br>Error executing command. Return code: $return_var";

if($error != null){

echo "<br><br>Last PHP error occurred: '" . $error['message'] . "'";

}

} else {

// The command ran successfully

echo "<br><br>Command executed successfully!";

// Output the STDOUT and STDERR from the bash script

echo "<br><br>Output:<br><br>";

foreach ($output as $line) {

echo htmlspecialchars($line).'<br>';

}

}

}

?>

You sure?

Following that up with a whoami may reveal otherwise.

I’m not sure why you’re jumping from PHP to bash… it would probably save a lot of headaches just doing whatever you need to do in PHP rather than passing a bunch of parameters around. Why not do mkdir and whatever else from PHP? Even if it still doesn’t work an error from PHP should expose the reason directly in the response rather than trying to figure out what went wrong in a shell script running in the context of a httpd.

2 Likes

Appreciate the comment, always cool when somebody helps out somebody who has hardly any idea what they’re doing.

I did put the whoami in the script and it confirmed it was www-data. I confirmed all the permissions were correct. I turned off app armor and confirmed that wasn’t the issue.

At which point I turned to Apache Server which seems to be limiting the reach of www-data from straying outside the www/html folder. There were some config options I tried to allow symbolic links, but no dice. Then I tried configuring an alias, that also didn’t work. Finally I mounted the folder into the www/html folder and now everything is working great.

HTML button fires off the PHP, PHP sends variables to the Bash Script, and the bash script can now do system stuff. I’m going to have it activate a venv, and then send the variables to my python script.

I’m sure there is a more elegant and secure way to do what I’m trying to do, but I want PHP/Javascript as my front end to run my python backend, but I need to activate the venv to do that. I know I can send variables to a python script from PHP directly, but I’m not sure how to activate the venv for the python execution.

But at this point it’s working so I’m going to keep coding my project.

1 Like

Nice job getting it working. You can also add

<Directory {your path here}>
    require all granted
</Directory>

to your apache config to open up access to other folders.

Heads up that PHPs default max_execution_time of 30 seconds may also be a potential issue.

2 Likes

What platform are you developing on? I ask this because there is usually a python package to do what you are trying to do. The best way to research your new project is probably go to Kimi or Z one of the main AI Chat bots. They often have a Free Model or account you can use. It usually required you to create an account. There are a lot of web packages that do frontend work and you can backend to python. Tell the AI what you want to do and ask for suggestions on the type of stack you should use.

Flask is often used for light web programming: Flask for python Web Development

2 Likes

I’ll take a look at that. I had a variation of that but maybe I didn’t get it quite right. Would be more elegant to have in the apache config rather than mounting the drive. Thanks!

I’m trying to make a front end of PHP/JS that gets a backend of python to use the API in comfy. Trying to automate my workflow in a way that makes sense for me. Devil I sorta-kinda-but-not-really know makes me think PHP and javascript will make an elegant way to grab images and clips and feed into various comfy workflows. At least at this point given I don’t know what I don’t know, and don’t even know what I think I know.

If you intend your form to be exposed to the public and the drive has other stuff on it then you may want to expose only what you need instead of the entire drive. If it’s private or the drive doesn’t have anything else on it then you already have it working so I wouldn’t worry about it too much…

Technically PHP is backend/server side while JS is front end/client side. It’s easy to confuse with comfyUI because both client and server typically run on the same machine.

I’ve never used ComfyUI but being implemented as a python based server with a web interface should make it relatively easy to both interact with and modify. ComfyUI also supports extensions so depending on what you’re trying to do you may be able to just write an extension that modifies the server and/or client behavior to suit your needs.

If you want your own custom interface to the comfyUI server then interacting with it directly from the browser via JS the same way the official comfyUI front end does is probably the most straight forward.

You may be able to skip running your own httpd, PHP and a separate python env altogether and just use comfy to serve whatever custom html/JS you like that interacts directly with the API.

1 Like

I think i sort of understand what you are trying to do. It’s pretty complicated. I have it (ComfyUI) downloaded from github and I looked through it using Visual Studio Code trying to get it working with my video card. I am using Roo + DeepSeek to analyze it. If I were playing around trying to write a custom frontend for it, I might look at Gradio. But, you should talk it over with an AI first. Like maybe The Big Z

1 Like

I’m on the last bit before I’d be ready to cook with gas, but it seems perhaps I made a poor assumption that throws this all into question.

I had assumed the www-data user could source a venv. But it seems like it cannot.

If I run this bash script with my regular user, it works great.

If my www-data user runs this script, it fails on the source line and the venv isn’t activated and therefore the python script comes back with errors since it can’t see its libraries.

The bash script is:

#!/bin/bash
source /var/www/html/comfy/venv/bin/activate
python3 I2T2I.py
deactivate

I’ve tried a couple other shebang lines and they work with my normal user, but www-data still can’t source the venv.

And I’ve got it working. I click my HTML button, it fires the PHP which executes the bash script, which loads the python, and out comes an AI generated image.

The trick for the bash script was getting rid of the source command and using these paths:

#!/bin/bash
export VIRTUAL_ENV="/var/www/html/comfy/venv"
export PATH="/var/www/html/comfy/venv/bin:/home/bh/.nvm/versions/node/v20.19.6/bin:/home/bh/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/bin/bash:/var/www/html/V/:/snap/bin"
python3 I2T2I.py

EDIT: turns out you can use the source command in the bash script with www-data and I didn’t have to do that silly path stuff. The issue was a folder not having the correct ACL permissions. Still wrapping my head around permissions. I had thought a user/group having permissions would be enough until I realized ACL had a say.

Pretty happy given that I started the day with this expensive box not booting. That was a nice surprise. Turns out that in my attempts to get Apache and www-data to work outside of the confines of var/www/html, I had changed the ownership of everything in the /var directory. Shockingly, other things use that directory and cared, like Gnome which wouldn’t load up. Glad I had backed up my /var directory and so I copied it back over with its permissions intact and bada bing, it worked out.

This is what happens when a dummy watches Wendell’s videos and then bites off more than he can chew trying to juggle linux, Apache, PHP and such without knowing much about any of it.

4 Likes

Keep at it, and you’ll have an education better than you could get after multiple years of university classes.

That’s exactly what I did. I screwed around and broke stuff until I figured things out. Later it took years before I was consistently seeing new material in school.

3 Likes