Exec command doesn't work as expected - php

I'm trying to launch a CLI command from a PHP script:
in particular I wanna use this command convert a.png a.tif to convert an image to tiff.
When I launch this command from CLI it works as expected but if I launch from a PHP script with the following code it doesn't create any tiff image in my folder:
$exec = "convert a.png a.tif";
exec($exec,$yaks,$err);
echo "<pre>";
print_r($yaks);
echo "$err";
echo "</pre>";
Moreover $yaks is empty and $err is set to 127.
I'm not an expert, why this doesn't work as expected?
Best regards
UPDATE
I used this command instead $exec = "convert 4.png 4.tif 2>&1"; and I got in return [0] => sh: convert: command not found
This seems to me strange since I can use it from CLI!
FINAL UPDATE
Thanks a lot guys!
$exec = "/usr/local/bin/convert a.png a.tif";
This command solved the problem!
You're great.

you should enter fullpath to "convert" and may be files.
err 127 - file not found

It looks like the 'convert' binary isn't in any of the directories on the PATH PHP is using. You could try using the full path, e.g. /opt/local/bin/convert or whatever the path is.
You could also modify the PATH used by PHP (but I don't know how).

The PHP script probably doesn't know where to find these things you're referring to in the exec command. When you run this from the command line, the shell will look for them in the directory you are in at that point in time; but when you run it from PHP, it probably defaults to the PHP dir and not the specific dir in which your files are. So write out the full path.

Related

Imagemagic and php exec: convert: no images defined

The command works just fine from the shell
/opt/ImageMagick/bin/convert /private/var/folders/nl/9cky1krj5_j7zwm34tfkndd40000gn/T/pdfPyflQF /private/var/folders/nl/9cky1krj5_j7zwm34tfkndd40000gn/T/imgRilIdW 2>&1
I got image generated. But if I run it with php exec function I get error
Array
(
[0] => convert: no images defined `/private/var/folders/nl/9cky1krj5_j7zwm34tfkndd40000gn/T/imgRilIdW' # error/convert.c/ConvertImageCommand/3212.
)
Seems it's not permission issue. File permissions are 666. Can't figure out what is wrong.
Usually error "convert: no images defined" is coming when convert couldn't find gs tool.
I had the same problem and solved it with defining PATH environment before doing shell_exec like this:
putenv('PATH=/usr/local/bin:/usr/bin:/bin:/opt/local/bin/');
Because gs tool is located in the /opt/local/bin.
I can not see a file extension on the input or output images.
It would probably be worth enclosing your image path in " " and what actual code are you using in exec()

PHP exec() with Pygments for PHP

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.

PHP exec command has no effect despite returning no error code

I'm running a command to add id3 metadata to mp3 files via PHP's exec function, like so:
exec('id3v2 [options, filename etc go here] 2>&1', $output, $result);
The command is currently having no effect on the target files (ie. their id3 tags are not being updated). However, it returns 0 as the $result, outputs no errors, and if I run the exact same command from the command line it works as expected.
If anyone could suggest what I'm doing wrong, I'd be very grateful!
Check the $output.
This is probably a path or access right issue. For example if you run this script with the web-server priviliges it probably doesn't have the right to alter the files.
Does the user PHP is running under have permissions to write to those files and execute "id3v2"?
Try http://www.php.net/manual/en/language.operators.execution.php
Or, if id3v2 returns something you can do http://php.net/manual/en/function.shell-exec.php

Why isn't this shell command giving the desired result?

I am using the wkhtmtoimage library on my server, and I have managed to get the output for the following command when I am running in PuTTY:
wkhtmltoimage www.google.com test.jpg
But, when I use the following shell command I don't get the output, and I don't know why.
$filnename = "test.jpg";
$url = "http://www.google.com";
shell_exec("wkhtmltoimage $url $filename");
Even I tried with this variation instead, but still without getting the desired result:
shell_exec("/usr/local/bin/wkhtmltoimage $url $filename");
What am I doing wrong?
Edit:
I downloaded the Linux binary and put it into the folder then I ran it.Whether I need to restart the server the changes affected?
shell_exec command is allowed because we used it for ffmpeg(already installed one)
I cannot give an exact solution but if you can try out what I write I might be of help. I will list more solutions if the one I am providing does not work.
Solution proposal 1:
Use quotes around url and filename
shell_exec("wkhtmltoimage \"$url\" \"$filename\"");
Solution proposal 2:
Try redirecting streams to files and type the contents.
shell_exec("wkhtmltoimage \"$url\" \"$filename\" > output.txt 2> error.txt");
May be user under which PHP (or Apache) runs have no permissions to run this tool. Try printing output of this command or just use passthru() to directly print output of command.
Another solution is to pass output to files as #Cem_Kalyoncu wrote.

Problems when trying to exectue exec("unix2dos xxx") in PHP/Apache

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.

Categories