I think that the issue is not that you not get the output of the executed command, but which fails to find mysql.
Using exec you can get the return status of your command, where 0 means successful, and other values indicate an error.
$output = exec(
output, $retval);
var_dump($output);
var_dump($retval);
If the $retval is 1 that would mean which doesn't find the mysql binary, and returns an empty line.
Hi all I'm trying to SvtAv1EncApp tools via web interface, I try to us both exec() shell_exec() with no success , BTW I print the command and run it into the shell directly and it's works perfectly fine.
$cmd2="/usr/local/bin/ffmpeg -loglevel -8 -i "$mp4" -s 960x540 -strict -1 -f yuv4mpegpipe - | /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log | /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "$mp4" -map 0:v -map 1:a:0 -c:v copy $a '".$mpa."_.mkv' & ";
shell_exec( $cmd2 ) ;
Here is the text of echo $cmd2 output
/usr/local/bin/ffmpeg -loglevel -8 -i "FHD.mp4" -s 960x540 -strict -1 -f yuv4mpegpipe - | /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log | /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "FHD.mp4" -map 0:v -map 1:a:0 -c:v copy -strict -2 -c:a libopus -b:a 64k 'FHD_.mkv' &
=Update=
I kinda solve it , I don't know why but exec() successfully executed the script , I created new bash script from command line thanks to @xisonc suggesting nano /usr/local/sbin/av1c with this value
!/bin/sh
touch /var/www/vl/ffmpeg.log /usr/local/bin/ffmpeg -loglevel -8 -i "$1" -s 960x540 -strict -1 -f yuv4mpegpipe -
| /usr/local/bin/SvtAv1EncApp --no-progress -i stdin --rc 0 -q 38 --preset 8 -b stdout 2>/var/www/vl/ffmpeg.log
| /usr/local/bin/ffmpeg -loglevel -8 -y -i - -i "$1" -map 0:v -map 1:a:0 -c:v copy -strict -2 -c:a libopus -b:a 64k "$2"
On the php script i had this
$cmd2="/usr/local/sbin/av1c '$mp4' '$mpa"."_.mkv' 2>/dev/null >/dev/null & " ; exec( $cmd2 , $pid, $r ) ; var_dump( $r ) ;
var_dump returns 0 , and since the bash script are silent I don't need to see the output , now I want to change it to wok on the background it's running on background now after adding 2>/dev/null >/dev/null & at the end of the command .
$output = shell_exec('mysql -u admin -padmin1234 -e \'create database `somedatabase`\'');
echo $output;
exec('mysql -u admin -padmin1234 -e \'create database `somedatabase`\'',$output_array);
print_r($output_array);
Both of exec and shell_exec result in creating the somedatabase database in mysql. But neither of these commands seem to capture the output. I know this command gives output because I can run it manually on the command line and see it. Is mysql just a special case or something? Running a simple command like ls -l works correctly, I can receive that output of that in PHP but cant for mysql for some reason.
Edit: Figured it out. The answer for me was understanding that 2> on the terminal catches the errors. So by using 2>&1 at the end of the command tells the terminal to redirect errors to the standard output (of which shell_exec will catch) https://stackoverflow.com/questions/52477206/how-to-redirect-mysql-output-to-file
Title is probably not clear enough but here is my problem, I have a program that when I run it from the console it goes through but for some reason from within my php code it doesn't work but the program doesn't exit, so I don't get any feedback, how can I get some feedback so that I can start debugging why it only works in the console?
I don't know how pdfgrep works but maybe it mixes stdout and stderr? Either way, you could use a construction like this, where you capture the output stream into an output buffer, optionally also mixing stderr into stdout:
$mixStdErrIntoStdOut = false;
ob_start();
$exitCode = 0;
if ($mixStdErrIntoStdOut)
{
system("pdfgrep -i $keyword $file 2>&1", &$exitCode);
} else {
system("pdfgrep -i $keyword $file", &$exitCode);
}
$output = ob_get_clean();
var_dump($output);
There are number of ways how you can execute the process and gather the output. If you can consistently repeat the problem, you may try other process execution methods:
1) exec($command, &$output)
$output = [];
exec($command, $output);
this should push all of the output, line-by-line, in your $output array, that has to be instantiated before calling this method.
2) passthru($command)
this would pass back into the output buffer all the output of the command. so to use this you need to use output buffer:
ob_start();
passthru($command);
$contents = ob_get_contents();
ob_end_clean();
3) popen($command, "r");
$output = "";
$handle = popen($command, "r");
while (!feof($handle)){
$output .= fread($handle, 4096);
}
Let me know what you get by calling each of the methods.
Also, make sure to check stderror for errors.
On the php manual for shell_exec, it shows that the function returns the output as a string. If you expect output from the program you launch, you need to capture this like so:
$execQuery = "echo -n test_command";
$output = shell_exec($execQuery);
echo $output;
Your question doesn't show trying to capture any data. If you also make sure to connect stdout and stderr when you run your command, you should get a better idea is what is going on. To use your example:
$output = shell_exec("/usr/bin/oneuser create test10 test10 2>&1");
var_dump($output);
That should help you see what is going on. As Shadur suggests, it seems likely that these programs expect an interactive terminal that can enter passwords in order to run. Even if don't need input, they might expect interactive shells. And he's right that su doesn't play nice in this context. There is, however, a correct tool for the job.
You can setup sudo to such that your http user can execute your program as username without a password but NOT be able to do anything else by running visudo or whatever you use to edit your sudoers file and adding this line:
http ALL=(username) /usr/bin/oneadmin
Then in php your command would look something like this:
$execQuery = "sudo -u username /usr/bin/oneadmin postgres -c '/usr/bin/oneuser create test10 test10'";
$out = shell_exec ("$execQuery 2>&1");
echo $out
Try passthru($cmd);
It will allow user's I/O on the Terminal screen.
You have to use 2>&1 after the restart command
Your command :
$command = "echo 1; /etc/init.d/apache3 restart; echo 2; 2>&1";
yours has "2>&1" at the end which has no use.
Also you will add to 2>&1 after each command in case others uses STDERR
$command = "echo 1; /etc/init.d/apache3 restart 2>&1; echo 2 ";
Consider using exec. The basis function only returns the first line of the output:
$response = exec("$command"); // just the first line
But use the additional parameters to capture both the output (as an array) and the return value
$retval = NULL;
$output = NULL;
$response = shell_exec("$command", $output, $retval); // last two params are passed by reference and modified by the command
Also, as user993553 posted, the output captured by these cli functions in PHP will usually just return stdout and not stderr. You can append " 2>&1" to any given command (note the space before the 2) in order to route stderr into the output.
That said, your function becomes:
$command = "echo 1; /etc/init.d/apache3 restart 2>&1; echo 2;";
$retval = NULL;
$output = NULL;
$response = exec($command, $output, $retval);
var_dump($output);
and the output:
array(3) {
[0] =>
string(1) "1"
[1] =>
string(37) "sh: 1: /etc/init.d/apache3: not found"
[2] =>
string(1) "2"
}
EDIT: you can also check $retval for an error condition. If it's not empty or zero, then signifies an error.
Because systemctl is not on your path (or not on you system) which systemctl returns the error message
/usr/bin/which: no systemctl in (/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin)
When you run it in PHP using shell_exec('which systemctl'); the standard error is not collected, and the standard out is empty. Hence PHP sees an empty string.
You can get standard error using this command:
shell_exec('which systemctl 2>&1');
I'm using passthru in my project like the code below:
$output = '';
ob_start();
passthru('which systemctl', $output);
$output = ob_get_contents();
ob_end_clean();
And shell_exec also return an output please see the doc here: http://php.net/manual/en/function.shell-exec.php
But either one passthru and shell_exec is working.
You should redirect stderr to stdout.
To do that, change your exec() call like this:
exec("ping -c 1 $domain_bad 2>&1", $output, $return_var);
More info about 2>&1 meaning here.
If the answer above could not solve your problem, maybe exec() is disabled. You can try to check php.ini file at disable_functions line.
I changed the sudoers to ALL ALL = (ALL) :NOPASSWD ALL (very un-secure, but just to find something sure to work),
then I did a
sudo -u myusername /path/to/script.sh
where script.sh has export VAR=value export VAR=value
for all the environmental variables that are necessary (you can do a printenv from a user who can properly pacmd to see what you need. probably a good HOME and maybe an XAUTHORITY).
hope that helps
You may want to try " > file.txt 2>&1" at the end of your command. It will redirect the outputs to a separate file.
$command = "cmd command > outputs.txt 2>&1";
shell_execute($command);
You'll end up with a file that looks something like this:
b'cmd command output contents\r\n'
There is a note in php manual page of shell_execute:
Note: This function can return NULL both when an error occurs or the program produces no output. It is not possible to detect execution failures using this function. exec() should be used when access to the program exit code is required.
Source: http://php.net/manual/en/function.shell-exec.php
So your code running with error. Try with exec. If you want, insert your code (or blocks) to be checked.
This is fixed by adding user used by web-server to sudoer and run the php command with
sudo php ..........
To start run this command sudo visudo
Add the following line at the end of sudoer file opened
www-data ALL=NOPASSWD: /usr/bin/php
But if you whant to execute all commad from php add this line instead of the above www-data ALL=NOPASSWD: ALL which is not recommended
and the run your commands with sudo php /path/to/you/file.php
For my case I was running ubuntu 14.04
Have fun please