[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 2011
  • Last Modified:

copy in php using shell_exec

hi,
I want to check the o/p of the shell_exec() after copying a file in linux
$cmd = 'cp -p /var/mangalsutrabandhan.com/123.mangalsutrabandhan_file.com /var/lovetomarry.com/test/ ';

echo $retval = shell_exec($cmd);

But its not copying the files if echo the same code and run it directly it works properly
1> copy file from one dir to other maintaining its property of time and user (i.e cp -p)
2>secondly i want to know the success and failure of the copy code.

its linux, php
0
Insoftservice
Asked:
Insoftservice
  • 9
  • 5
  • 3
  • +2
4 Solutions
 
Randy DownsOWNERCommented:
can you run the command manually?
0
 
InsoftserviceAuthor Commented:
ya,
the o/p of the echo  if i run directly it runs as expected.
0
 
InsoftserviceAuthor Commented:
if i use
       $domain = 'www.lovetomarry.com';
        $retval = shell_exec("whois $domain");

it gives the detail o/p so, shell_exec safe mode issue is not present i think so.
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 
Randy DownsOWNERCommented:
maybe try running with sudo as root
0
 
InsoftserviceAuthor Commented:
can u provide the code if possible.
but i doubt using sudo will be applicable here but even though please do provide it
0
 
Hugh McCurdyCommented:
There might be an error in the log file.  The log file might be /var/log/httpd/errors_log    The log file's name should be in your httpd.conf file.

Number-1 might be on to something.  

What user are you when you do the copy?
When you run PHP, are you running it from a command prompt or via the browser?

Getting to my point, if using the browser, does the user www, or apache, or whatever it's called on your system, have permissions to complete the copy operation?  
0
 
Randy DownsOWNERCommented:
Should be something like this

$cmd = 'sudo -u root cp -p /var/mangalsutrabandhan.com/123.mangalsutrabandhan_file.com /var/lovetomarry.com/test/ ';

If sudo requires a password you can turn it off or maybe include it like without quotes.
'sudo -u root -p"PASSWORD"

http://www.ducea.com/2006/06/18/linux-tips-password-usage-in-sudo-passwd-nopasswd/

NOPASSWD
If you don’t want to be prompted for any password while running sudo then we can use the NOPASSWD parameter on a particular entry:

admin    ALL = NOPASSWD: ALL


0
 
InsoftserviceAuthor Commented:
ya,
i am getting permission issue.
I am doing it via browser, but the php file owner and file to be copied owner are same.
with 755 rights
0
 
Hugh McCurdyCommented:
Why don't you do this just to make sure you have the owner right.

Remove the destination file.

Temporarily change the permissions of the target folder to 777.

Run the program.  It should work (I hope).

When it's done, do a listing of the target file and see who owns it.  (Make sure it is owned by the user who you think should own it.)


I often solve problems like this by making the owner of the folder me (or some other account that is supposed to have access to the file).  Then I set the group to www or apache (or whatever).  Set perms for the folder to 775 or 770.  Just an idea.
0
 
InsoftserviceAuthor Commented:
ya the permission issue got resolved.
But now how to get such error message to be displayed on screen.
as the error or warning has to be cpatured and has to be displayed on the screen
0
 
Hugh McCurdyCommented:
shell_exec() should return the output of the command.  Capture the return value.    http://php.net/manual/en/function.shell-exec.php

Print the return value (echo) in both a successful run and a failed run and see if it's useful.

0
 
InsoftserviceAuthor Commented:
hi,

i have used
echo $retval = shell_exec($cmd);
but it did not gives me any o/p even the permission error i had to check in log file.
0
 
Ray PaseurCommented:
Why not just put a PHP script on the server to do the copy?  
<?php // copyscript.php
error_reporting(E_ALL);
copy ($_GET["from"], $_GET["to"]);

You can add a layer of security, of course, but at least that way you will have a good chance of seeing any error messages.
0
 
InsoftserviceAuthor Commented:
we want to maintain the time properties of the file that would be copied.
0
 
Ray PaseurCommented:
Ahh, understood, thanks.   Strike my suggestion.
0
 
Hugh McCurdyCommented:
I had never actually tried getting the return value using the shell_exec().  I hoped it would work based on the documentation.  From writing programs in C, over the years, I suspected it might not work which is why I suggested looking at the output before actually relying on it.  Appears it doesn't work.

I don't have a good solution but went looking for a way to mimic what cp does with setting the timestamp on the file without actually writing C code.  I found this  
http://www.unix.com/shell-programming-scripting/127190-changing-file-time-stamp-bash-script.html

Those techniques could be used in addition to copying the file using PHP code.  Seems like a lot of work.

Another idea, which seems like a lot of work.

I know php has a touch command.  Now it's less work.  We just need the date from the old file.  This is likely possible but I've never done anything like that in PHP.

Ray, are you still there?
0
 
AnacreoCommented:
Did a quick mock of this this should do what you need in terms of catching all the vital results and displaying them back to the user if need be.  But key is to get the return_val in the pclose so you know if the copy worked and then to do the touch to replicate time.

Here is the code:
#!/run/php/bin/php
<?php
error_reporting(E_ALL);

/* Add redirection so we can get stderr. */
$source = 'test_script_source';
$dest = 'test_script_dest';
$cmd = 'cp -p ' .  escapeshellarg($source) . ' ' . escapeshellarg($dest);
$handle = popen($cmd  . ' 2>&1', 'r');
$output = stream_get_contents($handle);
$return_val = pclose($handle);

if ($return_val == 0) {
  echo "Command completed successfully: \n$output\n\n";

  touch($dest,
            filemtime($source),
            fileatime($source));
} else {
  echo "Copy command failed ($cmd)!\n$output\n\n";
}
?>

Open in new window


Here is what a run looks like:
124 ~/bin >ls -la test_script*
-rwxr-xr-x   1 user     other        567 Oct  5 23:53 test_script.php*
-rwxr-xr-x   1 user     other        853 Jul 25 10:41 test_script_dest*
126 ~/bin >chmod a-w test_script_dest
127 ~/bin >chmod a-r test_script_source
128 ~/bin >./test_script.php
Copy command failed (cp -p 'test_script_source' 'test_script_dest')!
cp: cannot open test_script_source: Permission denied


129 ~/bin >chmod a+r test_script_source
130 ~/bin >./test_script.php
Copy command failed (cp -p 'test_script_source' 'test_script_dest')!
cp: cannot create test_script_dest: Permission denied


131 ~/bin >chmod a+w test_script_dest
132 ~/bin >./test_script.php
Command completed successfully:


135 ~/bin >ls -la test_script*
-rwxr-xr-x   1 user     other        567 Oct  5 23:53 test_script.php*
-r-xr-xr-x   1 user     other        853 Jul 25 10:41 test_script_dest*
-r-xr-xr-x   1 user     other        853 Jul 25 10:41 test_script_source*

Open in new window

0
 
Hugh McCurdyCommented:
Anacreo, that looks good.  I thought the author said the return value wasn't working...  Working for you.
0
 
InsoftserviceAuthor Commented:
ya,
really thx for it let me chk for it.
i tried this one and it worked too.
 $retval = shell_exec($cmd.' > /dev/null; echo $?');
0 =>success
1=> for fail
but Anacreo is looking good let me chk it too
0
 
AnacreoCommented:
Well I'm using a different function than the shell_exec, but mainly because I wanted to capture the STDERR, so I append "2>&1" to the CMD string.

I'd really be careful with doing the shell_exec and not protecting your variables with escapeshellargs, so I set this up so the variables could be user input later (just make sure you pull out any kind of path data that could be prepended.

Lastly there is cp -p and the touch syntax.  The touch is superfulous with the cp -p (preserve) but the -p does more than touch, so I gave both syntax.  It might be that you don't want to copy the permissions, user, group, etc.  In this case drop the -p from cp command and keep the touch() function, or drop the extra touch() function.

If you introduce lag between the copy operation and touch, and you expect the source file to change, you may need to do a clearstatcache() before the touch routine, as the source file's timestamps will be cached.

Good luck hope you're able to find the right solution in this.

Alec
0
 
InsoftserviceAuthor Commented:
hi,

actually @hmccury had resolved my whole issue.
The rights issue even the operation has been performed or not. but Anacreo
answer has resolved the issue even for rest command if i used it later thx too all for there valuable time.
0

Featured Post

Efficient way to get backups off site to Azure

This user guide provides instructions on how to deploy and configure both a StoneFly Scale Out NAS Enterprise Cloud Drive virtual machine and Veeam Cloud Connect in the Microsoft Azure Cloud.

  • 9
  • 5
  • 3
  • +2
Tackle projects and never again get stuck behind a technical roadblock.
Join Now