【问题标题】:PHP: Strange Problems with shell_exec("mkdir") and shell_exec("rm -rf)PHP:shell_exec("mkdir") 和 shell_exec("rm -rf) 的奇怪问题
【发布时间】:2013-06-25 17:24:15
【问题描述】:

我正在编写一个 PHP 脚本来自动解压缩和扫描位于外部 USB 驱动器上的 tar.gz 档案,但我遇到了一些奇怪的问题。一旦脚本找到存档,它会尝试在 USB 驱动器上创建一个临时目录以将存档解压缩到。为了保证一个唯一的临时目录名称(因为此脚本可能同时运行多次),我使用当前时间的 MD5 的随机 5 位部分命名文件,如下所示:

$temp = "/media/$driveName/".substr(md5(microtime()), rand(0, 26), 5);

因为U盘没有挂载在服务器文件系统中,所以我不能使用PHP内置的文件管理命令(mkdir()、glob()等),只能通过终端与文件系统交互使用 exec() 或 shell_exec() 执行的命令。因此,要实际创建具有上述名称的临时目录,我使用了一个基本的终端 mkdir 命令:

shell_exec("mkdir $temp");

接下来,我将存档解压到临时目录:

shell_exec("tar -xzf $archivePath -C $temp");

最后,在我分析完档案后,我删除了临时目录及其内容:

shell_exec("rm -rf $temp");

但是,我遇到了两个奇怪的问题:

  1. 有时,可能每五次运行中就有一次使用损坏的名称创建临时目录。当使用ls directory 显示时,它看起来类似于06191v??????.???v???。但是,当使用 tab 键自动填写cd 命令时,它会填写更长的字符串,例如06191v\342\226\200\342\225\232.\342\211\2100v\342\226\200/。我知道在将字符串传递给 shell_exec() 之前该字符串很好(我什至尝试使用 substr() 将其限制为正确的长度,但无济于事),并且第一个斜杠后面的一系列字符(所以从 342 开始)总是相同的,不管前五个字符是什么(前五个和斜线之间的字符总是一个字母,但在其他方面是随机的)。然而,除此之外,我不知所措。

  2. 出于某种原因,我用来删除脚本末尾临时目录的shell_exec("rm -rf $temp"); 只有在我执行两次时才有效。如果我只执行一次,我会收到以下错误:rm: cannot remove '/media/FILESYSTEM/f3637': Directory not empty,这本身就很奇怪,因为-rf 应该覆盖此错误。这种行为也可以在服务器的命令提示符中重复。

我似乎无法在网上找到与这些问题中的任何一个相关的任何内容,所以我希望这只是我犯了一个愚蠢的错误,而不是我的安装或 USB 驱动器的问题。提前感谢您的帮助!

编辑:我实际上有可能与第一个问题有关的第三个问题。在运行shell_exec("tar -xzf") 命令解压缩我的存档后,生成的目录 always 附加了一些奇怪的字符。例如,对于使用名为 BOOT 的压缩目录的一次运行,解压缩目录在终端中显示为 BOOT??w??????.???w???,其回显输出显示为 BOOT²w▀╚.∙wâ–€。使用制表符将cd 命令填入此目录后,我得到一个具有几乎相同模式的字符串:BOOT\302\262w\342\226\200\342\225\232 2.\342\210\231w\342\226\200/。 99% 的情况下,这不会影响脚本的执行,但偶尔会导致脚本无法扫描目录。

【问题讨论】:

    标签: php corruption mkdir shell-exec rm


    【解决方案1】:

    对于#1,似乎有一些奇怪的角色进入了那里。

    在我的机器上试过了,它似乎工作:

    <?php
    
    for($x = 0; $x < 30 ; $x++)
        shell_exec('mkdir ' . substr(md5(microtime()), rand(0, 26), 5));
        sleep(1);
    

    我将变量从引号中分离出来,并用'.'重新添加

    -肯

    【讨论】:

    • 这个问题是我需要能够将临时目录的名称保存到一个变量中(我可以使用终端命令找到它,但这似乎是不必要的迂回)。我试过这样:shell_exec("mkdir " . $temp);但它似乎没有什么不同。
    • 你能把 $temp 变量回显出来吗?我的猜测是一些非 ASCII 字符正在进入那里。
    • 我试过了,还是一样的问题:ob_start(); echo $temp; $temp = ob_get_clean();
    • 输出是什么?这就是我要找的东西,尝试在临时文件的名称上使用类似这样的东西:stackoverflow.com/a/8781968/1234011 编辑:如果你在 Windows 上可能是这个答案:stackoverflow.com/a/8782114/1234011
    • 抱歉给您带来的误会!这是一些输出:/media/FILESYSTEM/1a8b7, /media/FILESYSTEM/df32b 但是,即使没有链接到的脚本,输出也是这样的;当我回显它时,$temp 的值总是显示得很好,即使它不是在我将它传递给shell_exec() 时。
    【解决方案2】:

    事实证明,所有三个问题都有相同的解决方案:在 USB 驱动器之外的某个位置制作临时存档。我不知道是什么导致了多余的字符,但是当我将临时目录位置移动到 Linux 的 /tmp 目录时,它们一劳永逸地消失了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-09
      • 2011-02-28
      • 2014-06-26
      • 2012-07-02
      • 2013-01-10
      • 1970-01-01
      • 2012-05-13
      • 2010-09-11
      相关资源
      最近更新 更多