I'm running the following command in the console without any problems:
ffmpeg -i /var/www/html/input.mp4 /var/www/html/output.mp3
But when I run the command in PHP, I get nothing:
<?php
shell_exec("ffmpeg -i /var/www/html/input.mp4 /var/www/html/output.mp3");
?>
Any idea what the problem is here? I've checked my CHMOD permissions, everything looks good. Anything else to check?
Thank you,
I would try running it with full path to ffmpeg. You can get the full path on unix by running which ffmpeg in the command line. My ubuntu box produces output like /usr/bin/ffmpeg. Use that full path in code:
<?php
shell_exec("/usr/bin/ffmpeg -i /var/www/html/input.mp4 /var/www/html/output.mp3");
?>
For sure (as written above) passing full path is to exec is a good idea. Also you should also redirect the error stream to the output you gather - add the " 2>&1" to the end of the command. Take a look at the first comment here.
Related
I am trying to run shell commands from PHP using
<?PHP
$output = shell_exec('gcloud --version'." 2>&1");
echo "$output";
?>
The output which I get is
sh: 1: gcloud: not found
When I try to do
shell_exec('ls -l')
It works as expected. I have related posts on StackOverflow to use Rest API instead on this. But I have created a big script with gcloud commands. I am running my shell scripts in Terminal in mac. Can anyone help me understand the issue. May be required to install sdk, tried that still got same issue.
You need to read up on Relative Path vs Absolute Path of a file/dir.
When you code shell_exec('gcloud --version'..., you are using relative path.
One way to resolve your issue is to specify the absolute path to gcloud command which can be determined from bash command line by typing:
which gcloud and you might get a result like
/usr/lib/google-cloud-sdk/bin/gcloud
Then, change your PHP code to shell_exec('/usr/lib/google-cloud-sdk/bin/gcloud --version'...
I'm currently using the Pygments for PHP plugin that is located here: http://derek.simkowiak.net/pygments-for-php/.
The line that actually calls Pygments from that code is an exec() passed: pygmentize -f html $extra_opts -l $language $temp_name as the command. This all works fine, and I get back the output and it is formatted by the plugin.
What I would like to happen at the same time is for Pygments to create an image of it, so I pass exec() a similar command: pygmentize -f png $extra_opts -l $language -o $full_image_path/$output_file.png $temp_name This is where I run into a problem. The image never shows up in the expected folder.
However, if I var_dump() that command string before I exec() it and take it and run it straight from the command line, it works fine.
I have tried echoing exec('whoami') which tells me that the PHP user is www-data. I've tried giving permissions to www-data and changing ownership to www-data on the folder where I store the images. I've also tried changing permissions to 777 just to see what would happen, and the answer is nothing.
Is there something I'm missing? I'm running out of ideas to try. Thank you!
Edit: Another thing that I've checked is the output from the exec command, and the return value. It outputs an empty array, and it returns 1 as the return value.
Edit 2: After seeing that that directory should be writeable/readable for the PHP user, is it possible that pygments doesn't have permission to write it as a specific user? I'm not sure this makes sense, as when I run it myself it works fine, and in fact, when PHP runs it with the HTML lexer, it is able to run. I'm not very experienced in Python, so I don't know if this is a potential issue.
I guess you cannot do it like this.
$output_file.png
Try
$file = $output_file.".png"
and substitute in the exec
Ended up being an issue with the font that was installed for use by the www-root user. Apparently the one that is used by default for Pygments was installed only for the user that I was running as when I use the command line.
The way I was able to figure this out, was running
exec("$command 2>&1", $out, $code);.
The extra 2>&1 redirects stderr into the output for me to see the issue.
The $out parameter showed the FontNotFound error that pygments was throwing.
I changed the font that Pygments used via the command line using: full,style=manni,cssclass=pygmentize_kbOKBd,font_name='DejaVu Sans Mono' -l php -o /srv/www/path/to/images/uploads/2513732976ad4b7.02729290.png /tmp/pygmentize_kbOKBd after finding which fonts I had available to me.
To see which fonts I had available to me as the user running the script, I just ran fc-list in an exec() command for Ubuntu, and checked the output of that for the list of available fonts.
My problem is pretty simple: I can run ffmpeg commands perfectly fine on my server from the command line, but some of these commands experience trouble when I try to execute them from a PHP script.
For example, the following works in the command line:
ffmpeg -i cat.mpeg cat.avi
When in my PHP script, it also works as:
exec("/usr/local/bin/ffmpeg -i cat.mpeg cat.avi", $output);
This, as I said, works fine. However, this line works from the command line, but not in a PHP script:
ffmpeg -i cat.mpeg -vf scale=480:360 cat2.mpeg
Trying to put that into an exec() produces nothing. I've tried with/without quotes around the dimensions, different formats, etc. From the dozens of different commands I have tried, it seems that any will work from PHP as long as they don't contain the -vf flag. Clearly it works on the server, as executing from the command line proceeds with no issue; is there something silly I am missing here?
I believe it' not about the -vf flag, but about its parameters scale=480:360. Try escapeshellcmd() for escaping the command prior to executing it.
I'm writing a class who let me access to recutils through PHP.
I have a 'database' file called books.rec in ../database/ and a script who runs my Recutils.php class.
My class simply launch system application with correct parameters.
But When I try to use recins with PHP's exec function, the command doesn't work will it work in command line.
This is the command that is executed by my script :
recins -f Title -v "Moi" -f Author -v "Moche" -f Location -v "loaned" -t Books ../database/books.rec
With PHP : Nothing, the record is not inserted (no error message at all too).
In terminal : OK, the command is well done and my record is inserted.
I also have a method to do a select operation using recsel and it works very well, will it use exactly the same file (and runs from exec too).
So, could someone explain me why the command don't work will another with the same file work ?
Thanks
PS : Further informations : http://www.gnu.org/software/recutils/
I would double check that you are running the command as the same user from the command line and your php script. That may be the problem. exec('whoami')
You said you had a script that starts your php script it should be the same user as that.
You might also want to running a simpler exec command to see if that will work first.
Other things to try:
Try checking stderr output exec('ls /tmp 2>&1', $out); This will redirect standard error to standard out so you get both.
Try using php's shell_exec() which will invoke a shell just like when you are running from the command line(eg. bash). shell_exec('ls /tmp 2>&1 >> /tmp/log') should even put all output into a log file.
I don't think this will help you but it is something to try if all else fails, set it as a background process and see if it completes. exec('nohup php process.php > process.out 2> process.err < /dev/null &'). The & will set the command to run in the background and let the script continue.
Good Luck
Is recins command accessible for PHP ? Also is path to books.rec correct ?
Try with absolute path.
In a previous post, I was trying to update the encoding for a download file from php. One of the suggestions was to run the unix2dos command before sending the file to the user. This works great when I run the command on the linux box, but when I try and run the command from php I get nothing. Here is what I tried:
$cmd = "unix2dos -n $fullPath $downloadFile";
echo exec($cmd, $out, $retVal);
This displays nothing to the screen, $retVal is 0, and $out is an empty string.
echo system($cmd, $retVal);
This displays nothing to the screen, $retVal is 0.
echo shell_exec($cmd);
This displays nothing to the screen.
I have also tried escaping the command and it parameters like:
$cmd = escapeshellcmd($cmd);
and
$cmd = "unix2dos ". escapeshellarg("-n \"$fullPath\" \"$downloadFile\"");
Please let me know if you see something that I am doing wrong.
Thanks!
Edit: Here is some info that may be helpful.
unix2dos version: 2.2 (1995.03.31)
php version 5.2.9
Running in apache 2 on in Redhat Enterprise Linux 4
Have you considered a pure PHP solution?
<?php
$unixfile = file_get_content('/location/of/file/');
$dosfile= str_replace("\n", "\r\n", $unixfile );
file_put_contents('/location/of/file/', $dosfile);
?>
Something like that should do it, although untested :)
Shadi
See which user the PHP exec command is running as:
<?php system('whoami'); ?>
If this command fails then you likely do not have permission to use exec() or system(), so check your INI files. But be sure to check the correct ones! On Debian systems there are separate Apache and CLI INI files stored at /etc/php5/apache/php.ini and /etc/php5/cli/php.ini respectively. Sorry I do not know the locations for RedHat.
If the whoami command succeeds, make sure that the unix2dos command can be run by the user that is shown, and that the same user is allowed to make changes to the files in question by using chmod or chown.
Are you using the full path to unix2dos? Perhaps the executable is in your path for your shell but not in the path that PHP is using.
My implementation of unix2dos produces no output. If the return value is 0 then the command succeeded and your file has been updated.
The only other thing I see is the -n option which my version doesn't seem to have. You should probably check your man page to see what options it supports
unix2dos does not display the file it converts. Therefor you must display it yourself. A very basic way to do it could be :
$cmd = "unix2dos -n $fullPath $downloadFile";
echo exec($cmd, $out, $retVal);
include "$fullPath."/".$downloadFile;
Using include is pretty dirty but quick and easy. A cleaner way would be to use fopen and read the file then display it.
You'd better create a function that enclose all the operation : conversion + display so you'll have everything at hands.
But, If I were you, I'd prefer to not use exec at all and use FileIterator with a trim on every line so you will not have to care about the carriage return nor deal with a hazardous shell binding.
Not sure about your exact problem, but debugging suggestion:
Try first setting $cmd to ls. See if that works. Then try using /bin/ls (use the full path.)
If those don't work, then there might be a problem with your PHP configuration - there might be a safemode parameter or something which disallows the use of exec(), shell_exec(), or system() functions.
I got the source code from here.
http://www.sfr-fresh.com/linux/misc/unix2dos-2.2.src.tar.gz
I compiled it and then ran the tool. This was my output:
rascher#danish:~/unix2dos$ ./a.out -n 1.txt 2.txt
unix2dos: converting file 1.txt to file 2.txt in DOS format ...
I think the problem is this: the program writes all of its output to stderr, rather than stdout. If you look at the source code, you can see "fprintf(stderr, ...)"
As far as I know, PHP will only read the part of your program's output that is sent to STDOUT. So to overcome this, it seems like you have to redirect the output of your program (unix2dos uses stderr) to stdout. To do this, try something like:
$cmd = "unix2dos -n $fullPath $downloadFile 2>&1"
The "2>" means "redirect stderr" and "&1" means "to stdout".
In either case, I would imagine that the file was converting properly, but since you weren't getting any of the expected output, you thought it was failing. Before making the change, check on the output file to see if it is in DOS or UNIX format.