TWO linux commands executed in background called by PHP exec() function - php

I try to execute two linux commands in background by single php exec() call.
My first command makes some files backup:
cp -r ../source ../destination
Second command creates a file "DONE.txt" when backup is complete:
touch ../destination/DONE.txt
Moreover I base on php manual and use following background exec() call:
exec('bash -c "exec nohup setsid '.$twoCommands.' > /dev/null 2>&1 &"');
The whole code is bellow:
exec('bash -c "exec nohup setsid { cp -r ../source ../destination && touch ../destination/DONE.txt; } > /dev/null 2>&1 &"');
And... it doesn't work:) But why?
If I use only one command:
exec('bash -c "exec nohup setsid cp -r ../source ../destination > /dev/null 2>&1 &"');
It works well:)

I have no idea why you're trying to make this so complicated. nohup and setsid are two completely separate functions, not arguments you pass to exec. Nor do you even need to call exec in the command itself; that's the point of using exec in PHP. Output redirection is only necessary if you need the PHP script to continue in the background after the exec call rather than waiting for it to finish.
[root#test~]# ll
total 8
drwxr-xr-x. 2 root root 24 Jun 27 13:40 source
[root#test~]# ll source
total 0
-rw-r--r--. 1 root root 0 Jun 27 13:40 1
-rw-r--r--. 1 root root 0 Jun 27 13:40 2
[root#test~]# php -a
Interactive shell
php > exec("cp -r ./source ./destination && touch ./destination/DONE.txt");
php > exit
[root#test~]# ll destination/
total 0
-rw-r--r--. 1 root root 0 Jun 27 13:44 1
-rw-r--r--. 1 root root 0 Jun 27 13:44 2
-rw-r--r--. 1 root root 0 Jun 27 13:44 DONE.txt
[root#test~]#

Related

php shell_exec and exec doesn't work with shell script

So this is my code for the raspberry pi to get a still shot from the raspicam and save it on a directory,
<?php
exec('raspistill -n -hf -o /var/www/img/image.jpg --timeout 1');
?>
I have given the ownership and the permission to read/write in that forlder using -R. so my ls -al in /var/www is this
drwxr-xr-x 3 www-data www-data 4096 Jun 19 08:05 .
drwxr-xr-x 12 root root 4096 Jun 19 05:54 ..
-rwxrwxrwx 1 www-data www-data 74 Jun 19 08:30 getImg
drwxrwxrwx 2 www-data www-data 4096 Jun 19 09:21 img
-rw-r--r-- 1 root root 70 Jun 19 10:07 index.php
getImg is the script i tried to run the script as a file like shell_exec('/bin/bash ./getImg'); that also doesn't work.
i have added /bash/bin and tried to run the script without using the script file too but that doesn't get the results.
How ever when i try to run the php file in the terminal, it creates the image as it normally should. So i figure this must be a permission issue, but what else should i do with the permissions? I have given all the rights to the directory.
EDIT
So I have found a workaround to this. since I don't know what the cause for the problem, i'd not mark this as an answer, but please vote it to appear at the top.
I now execute the script using the cgi scripts. I have created a shell script in the /usr/lib/cgi-bin/
#!/bin/bash
echo "Content-type:text/html\n"
sudo raspistill -vf -n -o /var/www/img/image.jpg --timeout 1200 --metering matrix
echo "Status: 204"
I saved this as capture and made this executable, did nothing with the permissions though.
sudo chmod +x capture
now when i open the link http://192.168.1.85/cgi-bin/capture the browser will still get me a 500 internal server error message. how ever, the image would still be created.
I would now need to get the 500 internal server error to be fixed.
[I'd add this as a comment but don't have enough points for it]
if you use the optional parameters $output and $return_var to capture the output and return value what do you get?
string exec ( string $command [, array &$output [, int &$return_var ]] )
does your command rely on environment variables that may be available when you run it as your user but not as www-data? (you can use the env command to check that)
does it still work if you run it via terminal after switching user to www-data?

Shell_exec nohup with nohup.out

Executing this code:
shell_exec('nohup command&');
or this
shell_exec('nohup command > /path/to/nohup.out 2>&1&');
But there is no nohup.out in both cases. How can I run nohup with nohup.out via php?
shell_exec('nohup command > /path/to/nohup.out 2>&1&');
This line will work. Just make sure you have write permissions for the output folder. Consider your output folder is /usr/nohup-out
ls -l /usr/nohup-out
It should have write, read and execute permissions (rwx). If not, do this:
sudo chmod -R 777 /usr/nohup-out
Now, try to execute php file. It should create a nohup file in /usr/nohup-out folder.
Sample script and result:
1. date.php:
<?php
shell_exec('nohup date > /usr/nohup-out/nohup.out 2>&1&');
?>
2. Execute php from terminal:
php date.php
3. nohup.out content after execution
Thu Apr 23 11:30:28 IST 2015

PHP execute a script in the background

I have to execute a php script (a.php) in the background. I tried this but it's not working:
<?
$cmd = "php /home/megad404/www/prove/a.php &> /dev/null &";
exec('/bin/bash -c "'.$cmd.'"',$output,$return);
if($return===0)
{
echo 'Successful';
}
else
{
echo 'Unsuccessful';
}
?>
It returns "Successful" but it doesn't execute a.php
a.php:
<?
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
sleep(5);
file_put_contents(date("s"),"");
?>
a.php writes a file every 5 second and it works fine, except if I try to execute it in the background with the first script.
You can try adapt mi script.
Look a command shell_exec() not exec(). First return all , second only last line.
function run_in_background($Command, $Priority = 0) {
if($Priority)
$PID = shell_exec("nohup nice -n $Priority $Command > /dev/null & echo $!");
else
$PID = shell_exec("nohup $Command > /dev/null & echo $!");
return($PID);
}
//Verifies if a process is running in linux
function is_process_running($PID) {
exec("ps $PID", $ProcessState);
return(count($ProcessState) >= 2);
}
and example
$PIDPHP=run_in_background("php -S 127.0.0.1:18086 ".__DIR__."/index.php"); // or any other process.
if (is_process_running($PIDPHP)){
exec("kill $PIDPHP");
}
You could also look into using real Posix/PCNTL functionality to actually detach the script to background, eg. with pcntl_exec and pcntl_fork(). This is after my opinion the right way to handle background scripts that runs for a longer period of time as you can communicate with the child/process to get updates, status and so on and even have them understand real signal handling.
PCNTL - http://www.php.net/manual/en/book.pcntl.php
POSIX - http://www.php.net/manual/en/book.posix.php
Cheers
This just worked for me:
<?php
$cmd = "/usr/bin/php /home/auser/a.php &> /dev/null &";
exec($cmd,$output,$return);
sleep(30);
if($return===0)
{
echo 'Successful';
}
else
{
echo 'Unsuccessful';
}
?>
I saved it as runa.php and ran it from the command window as php runa.php.
It produced 3 files.
running a.php also worked from the cron job:
]$ crontab -l
18 * * * * /usr/bin/php /home/auser/a.php
I put the script in a web directory and find that I have some writing problems. What can you see in the server log?
sudo tail -f /var/log/httpd/error_log
And what if you hit a.php from the web browser? Because you mention the script is 755, but how about the directory. Maybe it needs to be 775 or 777 for testing so that the script can write a file?
For testing I created a sub directory "output" and changed a.php
<?php
ini_set('date.timezone','America/New_York'); //without this it makes extra messages
error_log("a.php putting contents", 0);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
sleep(5);
file_put_contents("output/".date("s"),"");
error_log("a.php done", 0);
?>
It was unable to write files until I gave write permission to the ouput folder
sudo chmod 777 /var/www/html/output
Then I found out the apache user is writing the files:
~]$ sudo ls -l /var/www/html/output/
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 00
-rw-r--r--. 1 apache apache 0 Apr 18 11:38 05
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55
So I changed the owner of output, in order to tone down the permissiosn again.
~]$ sudo ls -lu /var/www/html/ | grep output
drwxr-xr-x. 2 apache root 4096 Apr 18 12:21 output
This also works now:
~]$ sudo ls -l /var/www/html/output
total 0
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 44
-rw-r--r--. 1 apache apache 0 Apr 18 12:21 49
-rw-r--r--. 1 apache apache 0 Apr 18 11:37 55

PHPAGI: Exec format error

Encountering a problem when running phpagi:
-- Executing [123#DLPN_C:1] AGI("SIP/1000-00000001", "hello_world.php") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/hello_world.php
hello_world.php: Failed to execute '/var/lib/asterisk/agi-bin/hello_world.php': Exec format error
-- Auto fallthrough, channel 'SIP/1000-00000001' status is 'UNKNOWN' Scheduling destruction of SIP dialog '343930130' in 32000 ms (Method: INVITE)
From command line:
root#asterisk-test:/var/lib/asterisk/agi-bin# php5 -q hello_world.php
#!/usr/bin/php5 -q
Additional info:
-rwxr-xr-x 1 root root 757 Mar 29 19:32 hello_world.php
drwxrwxr-x 4 root root 4096 Mar 29 19:44 phpagi
-rwxr-xr-x 1 root root 25079 Sep 30 2010 phpagi-asmanager.php
-rwxr-xr-x 1 root root 2322 Sep 30 2010 phpagi-fastagi.php
-rwxr-xr-x 1 root root 67615 Sep 30 2010 phpagi.php
Source of hello world: http://www.eder.us/projects/phpagi/phpagi/api-docs/__examplesource/exsource_home_html_projects_phpagi_phpagi_examples_dtmf.php_acb7257145e4a5249182c8373cd8e848.html
The Exec Format Error is from /bin/bash, asterisk executes hello_world.php as a bash script.
shebang
If you add a correct shebang, the script get executed by the given PHP intepreter.
The first Line tells the System which program should run the script.
#!/usr/bin/env php
To test your shebang, execute the script itself, not by PHP:
root#asterisk-test:/var/lib/asterisk/agi-bin# ./hello_world.php
Make sure it is executable with:
root#asterisk-test:/var/lib/asterisk/agi-bin# chmod +x hello_world.php
alternative wrapper
Create a bash script that executes the PHP script.
example hello_world.sh:
/usr/bin/php hello_world.php
and call it in the Dialplan AGI("hello_world.sh").
Make sure the shellscript is executable chmod +x hello_world.sh.
I added following line on top script to get it working for me
#!/usr/bin/php -q
You issue is not asterisk issue,but general linux one.
Please try from your command line following:
su asterisk -c "/var/lib/asterisk/agi-bin/hello_world.php"
Most likly reasons: php path is incorrect or selinux enabled and not configured.
Could you check your extensions.conf or extensions_custom.conf, if the extension and priority are not continuous also this error will occur.
please check the below example:
[context]
exten => 1,1,Answer()
exten => 1,2,AGI(your-agi-script)
exten => 1,3,Hangup()

ffmpeg run from command line executes, from mod_fcgi truncates after completion

The ffmpeg from command line generates preview files and two separate two-pass conversion that when run from a shell script, execute successfully.
Running the commands via php's exec(/usr/bin/ffmpeg) or through exec(name_of_shell_script) generates preview files successfully. THe strange behavior is that the movies will generate, then truncate. ffmpeg log files are generated successfully, the out put file I can watch grow in size as the conversion continues, and then, when complete it appears, the files are truncated....
The only things that have changed on the system are changing from mod_php to mod_fcgi and php_cgi, but the error logs show nothing unusual except for
mod_fcgid: stderr: wmv, files3/1qwj, 1qwj.wmv
supressing output of the shell
scriptname.sh > /dev/null 2>&1
does not change the outcome.
should shell_exec be used? Is it a unix permissioning?
This is in ubuntu 10.04.1
This solution doesn't apply
FFMPEG running in Command Line but not PHP
EDIT:
looks like it might have something to do with the two pass encoding. The two pass encoding works fine from command line, but from the PHP env the shell overwrites something on the second pass.
nice -n 11 /usr/bin/ffmpeg -y -i $1 -r 30000/1001 -b 1M -bt 2M -vcodec libx264 -threads 0 -pass 1 -vpre /usr/share/ffmpeg/libx264-fastfirstpass.ffpreset -an movie.flv
nice -n 11 /usr/bin/ffmpeg -y -i $1 -r 30000/1001 -b 1M -bt 2M -vcodec libx264 -threads 0 -pass 2 -vpre /usr/share/ffmpeg/libx264-hq.ffpreset -acodec libfaac -ac 2 -ar 48000 -ab 192k movie.flv
$1 is the input filename
found
https://roundup.ffmpeg.org/issue1829
Edit:
when done here are the log file artifacts
-rw-r--r-- 1 www-data www-data 0 2010-09-19 19:02 ffmpeg2pass-0.log
-rw-r--r-- 1 www-data www-data 0 2010-09-19 19:02 movie.flv
-rw-r--r-- 1 www-data www-data 153466 2010-09-19 19:02 movie.jpg
-rw-r--r-- 1 www-data www-data 358803 2010-09-19 19:02 movie_preview.jpg
-rw-r--r-- 1 www-data www-data 410283 2010-09-19 19:02 x264_2pass.log
-rw-r--r-- 1 www-data www-data 5759257 2010-09-19 19:02 x264_2pass.log.mbtree
opened new ticket at request of maintainer
https://roundup.ffmpeg.org/issue2238
Edit:
looks like the issue is the audio for wmv files
http://ubuntuforums.org/showthread.php?t=1074152
Issue went away by updating ffmpeg and compiling.
wmv pro audio files are now supported in ffmpeg, and the installation I was using did not support.

Categories