1

Should shell commands be used for PHP file management?

Specific needs are deleting a directory along with all files in it, and copying or moving a directory to a new location with all included files/directories.

Either assume the script will be used only on a Linux operating system, or if not, steps will be taken serverside to detect the operating system and perform the correct shell commands.

Please give your reasons for your answer.

Thank you

EDIT. Response to Ganesh Ghalame's post. Below are some untested implementations of both. Why use the later?

<?php
//bla bla bla
rrmdir($dir);
recurse_copy($src,$dst);
rcopy($src, $dst);
?>


//Option command shell commands
<?php

function rrmdir($dir) { 
    shell('rm -fr '.$dir);
}
function recurse_copy($src,$dst) { 
    shell('rm -fr '.$dst);
    shell('cp '.$src.' '.$dst);
}
function rcopy($src,$dst) { 
    recurse_copy($src,$dst);
}


?>

//Option using PHP commands
<?php

function rrmdir($dir) { 
    if (is_dir($dir)) { 
        $objects = scandir($dir); 
        foreach ($objects as $object) { 
            if ($object != "." && $object != "..") { 
                if (filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object); 
            } 
        } 
        reset($objects); 
        rmdir($dir); 
    } 
}
function recurse_copy($src,$dst) { 
    $dir = opendir($src); 
    @mkdir($dst); 
    while(false !== ( $file = readdir($dir)) ) { 
        if (( $file != '.' ) && ( $file != '..' )) { 
            if ( is_dir($src . '/' . $file) ) { 
                recurse_copy($src . '/' . $file,$dst . '/' . $file); 
            } 
            else { 
                copy($src . '/' . $file,$dst . '/' . $file); 
            } 
        } 
    } 
    closedir($dir); 
}

// Function to remove folders and files 
function rrmdir($dir) {
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file)
            if ($file != "." && $file != "..") rrmdir("$dir/$file");
            rmdir($dir);
    }
    else if (file_exists($dir)) unlink($dir);
}

// Function to Copy folders and files       
function rcopy($src, $dst) {
    if (file_exists ( $dst ))
        rrmdir ( $dst );
    if (is_dir ( $src )) {
        mkdir ( $dst );
        $files = scandir ( $src );
        foreach ( $files as $file )
            if ($file != "." && $file != "..")
                rcopy ( "$src/$file", "$dst/$file" );
    } else if (file_exists ( $src ))
        copy ( $src, $dst );
}

?>
user1032531
  • 24,767
  • 68
  • 217
  • 387
  • it depends ;-) i use what ever is simpler- 1 file `unlink`, a wild card delete `rm`. if i need error control then probably php –  Aug 19 '15 at 04:36
  • @recommended closer. Too opinion based? Maybe I agree given my stated question, but I do think there is a right answer. Did I not provide enough qualification, and do you have thoughts how to make a better question? – user1032531 Aug 19 '15 at 04:38
  • there is no *right* here, it is both an opinion and very dependent on circumstances. –  Aug 19 '15 at 04:41
  • @Dagon Fair answer! So you are comfortable using `rm -fr bla/bla/*` providing you validate beforehand and use appropriate PHP operating usernames for file access? – user1032531 Aug 19 '15 at 04:42
  • much easier wildcards remove with rm than an unlink loop –  Aug 19 '15 at 04:42
  • Yes, much easier! Back to your earlier claim that it is `very dependent on circumstances`, can't disagree. What could I imply so it is no so? – user1032531 Aug 19 '15 at 04:45
  • Won't that make it immediately non-portable, at least to Windows, and then possibly to, say, BSD systems with slightly different utilities? – Waleed Khan Aug 19 '15 at 04:55
  • well if you host on windows you deserve to suffer ;-) –  Aug 19 '15 at 04:56

2 Answers2

1

Rather than adding Operating system specific code, why can't you use PHP ?

  1. Deleting Directory PHP Manual rmdir, Example check this
  2. Copying Directory PHP Manual copy, Example copy recursive
  3. Move Directory stack overflow possible duplicate

Alternative of using shell script which works for linux only

system('/bin/rm -rf ' . escapeshellarg($dir));
Community
  • 1
  • 1
Ganesh Ghalame
  • 6,367
  • 3
  • 24
  • 29
  • yes a list of php functions congrats on the insight, –  Aug 19 '15 at 04:59
  • Hi Ganish, I did look at each of your recommended solutions, but still don't know know "why"? Please look at my original post where I added each and a possible alternative. Thanks – user1032531 Aug 19 '15 at 05:07
  • If you use PHP approach your code will work on any operating system, but if you use approach of using shell script it only work on linux only – Ganesh Ghalame Aug 19 '15 at 05:17
  • Please look at my original post: `Either assume the script will be used only on a Linux operating system, or if not, steps will be taken serverside to detect the operating system and perform the correct shell commands.` – user1032531 Aug 19 '15 at 05:18
  • 1
    You wanted to copy, delete, or move directories for this purpose why are wasting your time to write the code for detecting OS and writing OS specific code ? Its bad practice to have environment specific code. – Ganesh Ghalame Aug 19 '15 at 05:23
  • If you use shell command like shell_exec you have to do additional settings to enable it, check this manual page http://php.net/manual/en/function.shell-exec.php – Ganesh Ghalame Aug 19 '15 at 05:29
  • I am using it elsewhere in the application, and it is already enabled. Why is it bad practice to use assuming it is documented? – user1032531 Aug 19 '15 at 05:31
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/87339/discussion-between-ganesh-ghalame-and-user1032531). – Ganesh Ghalame Aug 19 '15 at 05:32
-1

No.

Qualification: Not if a native PHP function exists to meet the same requirement.

Are you feeding user defined data into the shell command? What if the user adds a semicolon and some malicious code?

Have a read of this article: http://www.golemtechnologies.com/articles/shell-injection

  1. Using shell requires a whole lot more complexity to ensure security, so unless there's something really obscure you need to do (I can't think of anything that would match that), it's an unnecessary risk.

  2. Shell arguments make assumptions about specific operating system behaviours. If you know you will always be on debian/redhat/osx/windows then perhaps you don't care. Maybe someone else will later however. This is more of a 'good practice' factor.

Tim Ogilvy
  • 1,923
  • 1
  • 24
  • 36
  • Thanks Tim, Please assume that I am using `escapeshellarg()` and similar precautions. Why support some big PHP loop function when something is so much simpler. And as you stated, `not if a native PHP function exists to meet the same requirement` and I don't think one does. – user1032531 Aug 19 '15 at 05:28
  • I added a second reason. There are also an abundance of functions and plugins and so on around to do the recursive copy, some here: http://stackoverflow.com/questions/2050859/copy-entire-contents-of-a-directory-to-another-using-php – Tim Ogilvy Aug 19 '15 at 05:36
  • Thanks again. Yes, I know of the abundance of functions/plugins, but don't know how much I should trust them... – user1032531 Aug 19 '15 at 05:43
  • I would trust something like the symfony filesystem component more so than a bunch of cobbled together SO functions. It also comes with the perks that if something turns out to be exploitable, a team of other users will plug the whole faster than you or I could probably manage on our own. We're really getting into some heavy personal preference and opinion here tho. – Tim Ogilvy Aug 19 '15 at 05:46
  • Yea, if we get into the weeds of using a framework, I am off the island. Hoped not to go there. – user1032531 Aug 19 '15 at 05:50