PHP popen shell script not executing

Hi folks,

I am migrating from another hosting provider and am stuck on a call I am using to send e-mail from my PHP web app. This worked appropriately on the other hosting provider, but can't get it working on Linode.

From the PHP code executed from a form POST I call:

pclose(popen("/bin/sh /path/to/script.sh", "r"));

The script.sh shell script uses curl to call back to a PHP file that does the work of sending an e-mail. I am able to successfully run the following from the command line:

/bin/sh /path/to/script.sh

Any thoughts on flags to twiddle somewhere? Or better yet, any logs I can look at to see where it is breaking down? Apache error and access logs show nothing.

Also, I broke out the pclose() and popen() calls and echo'd the results of:

popen: Resource id #15
pclose: 2

Thanks, Josh

6 Replies

http://php.net/manual/en/function.pclose.php
> Return Values

Returns the termination status of the process that was run. In case of an error then -1 is returned.
So, sh or your script returns 2.

Assuming it's sh, errno == 2 is ENOENT, i.e. "file not found", which'd mean you're giving it a wrong path to the script.

If it's returned by your script, well, it depends what it's doing.

Also… why are you doing popen(pclose()), instead of system() or exec(), assuming you don't care about the script's output?

I just ran file_exists() on both "/bin/sh" and the shell script I want to execute. Both return TRUE.

I am using pclose(popen()) because I had previously read that this will run asynchronously, and therefore will not extend the waiting time for the person in the web browser. I do not care about the script's output; I just want it to fire off ASAP without stalling the website visitor.

Any other suggestions for what I want to do?

Thanks, Josh

Well, good idea would be to catch the stdout and stderr, instead of discarding it, and read the output. There may be some "useful" error message there. >.>

yawn something like

$handle = popen("/bin/sh /path/to/script.sh 2>&1", "r");
$output="";
if($handle) {
  while($tmp = fgets($handle))
      $output .= $tmp;
  $output .= "\n\nResult = " . pclose($handle);
}
else $output = "popen failed";
echo $output;

maybe?

Also, enable errorreporting (EALL) and chec out the php error log?

Nothing shows up in the PHP error log related to this.

The results I got from your code are:

/bin/sh: Can't open /path/to/script.sh

Result = 2

So, I opened up read to this script.sh for the world

chmod 755 script.sh

Now it works. Can you tell me what user would be running this process so I can amend their groups to include this script.sh file?

Thanks, Josh

Usually, the webserver user - httpd,nobody,www-data - depends on what distribution you use.

You can run 'ps axu' and see what username on far left is linked to the apache (or whatever web server you're using) processes on far right.

If you're using suexec/suphp, it's more complicated… it's either specified in some config file, or owner of the script, I'm not sure.

Thanks, it was www-data. Now it is all working.

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct