can any one please let me know, why i could not get result for the php function
exec('unzip gallery.zip',$return);
print_r($return);
Did you check the return value from unzip? Error messages are not given on standard output stream, so the array will be empty if something fails.
<?php
$result = array();
exec("unzip archiv.zip", $result, $returnval);
print_r($result);
print_r($returnval);
?>
Does the unzip work as expected? It might ask for overwriting etc. if the files already exist and stop the workflow. This output will not be captured in the result.
Have you initialized variable $return before use?
Have you installed package unzip if you're running Unix or Linux? (I'm not sure that you can do that on Windows)
Errors are written to stderr and aren't shown when using exec, backticks or shell_exec functions.
passthru() does output the error stream (as well as stdout).
Ps : Its probably either:
File not found: Does gallery.zip exists in the cwd. Use absolute paths and escapeshellarg() te be sure.
or
File rights: Is php allowed to write the extracted files to the cwd or specified targetpath?
Related
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
I am trying to run a shell from one of my controllers in a PHP codeigniter applications,
I am trying to run the file /x/sh/xpay4.sh however I just get 127 returned to the screen, I can even use basic commands like ls or pwd can any suggest why this would be, I thought it might be safe_mode when I ini_get('safe_mode') it returns 1
system function is restricted in safe mode.
You can only execute executables
within the safe_mode_exec_dir. For
practical reasons it's currently not
allowed to have .. components in the
path to the executable.
escapeshellcmd() is executed on the
argument of this function.
http://www.php.net/manual/en/features.safe-mode.functions.php
system() returns only the last line of the shell output.
Sounds likt this is "127".
If you need the whole output instead, try:
$output = array();
exec('/x/sh/xpay4.sh', $output);
echo implode("<br>", $output);
I am trying to run lame from a php script.
I have tried these, but no luck, I don't get anything returned! Any ideas?
system('lame', $returnarr);
system('lame --help', $returnarr);
exec('lame', $returnarr);
passthru('lame', $returnarr);
even this one returns nothing:
exec('which lame', $returnarr);
I am on OSX and final deployment will be on Linux. Do you have better suggestions for an automated wav->mp3 conversion?
From php, should I execute a bash script that executes Lame?
Try something like this:
$output = array();
$result = -1;
exec('`/usr/bin/which lame` --help 2>&1', $output, $result);
var_dump($output, $result);
$output should be an array of lines contained in the output
$result should be an integer result code. 0 is typically success, >=1 is an error (specific codes are application dependant).
The 2>&1 part will redirect STDERR to STDOUT ($output) which would normally be dropped. So if it's erroring out, you should be able to see the error (hopefully).
If you get -1 for the dump of $result, there's a fundimental problem, because that's not a valid result code (it likely means that exec is disabled, or the process you're trying to run is restricted because of permissions errors or the such)...
If you feel a need for more convenient way to work with lame, I would recommend to use phplame wrapper. Install PHP LAME wrapper using Composer:
{
"require": {
"b-b3rn4rd/phplame": "dev-master"
}
}
set error reporting on and check if you can do exec's. By default most systems wont allow it, it's a serious security liability. You've got to explicitly allow execs in php.ini.
Might be a $PATH problem. Try specifying the full path to lame, ie. /usr/local/bin/lame.
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.
This is driving me crazy. I'm trying to execute a command line statement on a windows box for my PHP web app. It's running on windows XP, IIS5.1. The web app is running fine, but I cannot get #exec() to work with a specific contactenated variable. My command construction looks like this:
$cmd = ($config->svn." cat ".$this->repConfig->svnParams().quote($path).' -r '.$rev.' > '.quote($filename));
This command does not work as is above, when it generates the following string:
svn --non-interactive --config-dir /tmp cat "file:///c:/temp/test/acccount/dbo_sproctest.sql" -r 1 > "C:\Inetpub\sites\websvn\temp\wsv5B45.tmp"
If I copy/paste this to my own command line, it works fine.
If I hard code that very same path instead of adding it with the variable, it works! I've tried with and without quotes around the file name. I've tried with and without quotes around the entire command. I've tried other directories. I've tried passing an output paramter to exec(), and it comes back empty (Array () ). I've tried redirecting the output of the error stream of the command to a file, and that error output file never gets created.
The only thing I can possibly concieve of is that exec() is failing silently. What on earth am I doing wrong here? If I hard code the file path, using the same dir structure and filename, it works fine. If I don't, it doesn't.
Maybe the slashes () in the file path aren't being escaped properly, but when I do it manually with single quotes they are not considered escape sequences??
UPDATE:
I took the # off of exec, and still not seeing any errors.
I gave the full path to SVN, still no luck. It should be noted that the command worked fine before with the non-full path SVN so long as I manually specify the file destination for cat.
Update 2: RE: Kieth
I'm calling exec by trying both:
exec($cmd);
or
exec($cmd, $out);
My php.ini already had safe_mode = 0.
I added error_reporting(E_ALL); and didn't see anything new
If I echo (or print_r) my exec call, I am not actually seing anything
If I echo (or print_r) my exec call when included an output var, I get an empty arr
Update 3
I tried both escapeshellcmd and escapeshellarg to no avail (good idea though).
I should add that the file is being created through invoking
tempnam("temp", "wbsn");
The fact that it works just fine if I manually specify the string instead of letting it be generated by tempname seems to suggests that the source of the problem, but I can't figure out how. I did a comparison of the manual string with the one generated, and it came back as a match.
#exec will always fail silently, because # is PHP's error suppression operator.
Not sure if this will help you since you're on Windows and I'm on Linux, but I ran into this same problem of silent errors from PHP exec(). I figured out that the command I was attempting to issue (nconvert) sends its error messages to the standard error stream, not standard out. So I added
2>&1
at the end of the command line to redirect my error back to the standard stream. Then I could see that nconvert was giving me a permission denied error.
It could be that the PATH isn't the same from your php script vs your user account. Try removing the # and see if it's trying to throw an error.
In addition, you may want to try putting the full filesystem path to the SVN executable.
Well, if removing # isn't working, try including this at the start of the piece of code you're running:
error_reporting(E_ALL);
That'll turn on full error reporting, just in case you have it turned down or disabled in your php.ini file.
I don't suppose you could show us how exactly you're calling exec()? Could you also check to make sure you're not accidentally running the script in safe mode? Are you echoing out what exec() is returning, and if so, what is it returning?
I'm not a big fan of adding another response, but if I just edit my previous response, you may not see it.
PHP has some special escaping commands for shell scripts: escapeshellcmd and escapeshellarg.
I think you should be able to use escapeshellcmd around your entire $cmd, but I'm not sure.
Have you tried echo exec("dir") or something simple to see if exec() is working at all?
I don't know what going on, but I at least have a workaround.
This works:
$tmp = tempnam("./", "wbsn");
$filename = dirname($tmp).'\\temp\\'.basename($tmp);
This, however, does not, but I would have expected it to generate the same path (diff file name since it's a new tempnam()).
$tmp = tempnam("temp", "wbsn");
Also, this does not work, which I also would expect to generate the same thing:
$tmp = tempnam("temp", "wbsn");
$filename = dirname($tmp).'\\'.basename($tmp);
All 3 of these solutions appear to generate the same file paths, but only the first one actually works when used in my exec. I have no clue why it does not.
Visual inspection (echo) of all 3 of these appear to generate the same paths (with the exception of filenames differing, of course). A string comparison of dirname() of each of these 3 shows as a match. I have no clue what the deal is, but the first one is a workaround.
A very useful trick when debugging shell exec problems is to place an "echo" at the beginning of the command. Make sure that you can view the standard output somewhere.
This will let you examine the command for any obvious problems. Perhaps it has a wildcard that is expanding unexpectedly, or perhaps the shell quoting is not exactly right. The echo will let you see this, and you can cut and paste the echoed command into another shell to see if it is working properly.
My advice will be to switch from WIN, IIS to linux, but as alternative you can try this:
function exec_alt($cmd) {
exec($cmd, $output);
if (!$output) {
/**
* FIXME: for some reason exec() returns empty output array #mine,'s machine.
* Somehow proc_open() approach (below) works, but doesn't work at
* test machines - same empty output with both pipes and temporary
* files (not we bypass shell wrapper). So use it as a fallback.
*/
$output = array();
$handle = proc_open($cmd, array(1 => array('pipe', 'w')), $pipes, null, null, array('bypass_shell' => true));
if (is_resource($handle)) {
$output = explode("\n", stream_get_contents($pipes[1]));
fclose($pipes[1]);
proc_close($handle);
}
}
return $output; }