PHP:使用shell_exec("mkdir")和shell_exec("rm -rf")出现奇怪问题

3
我正在编写一个PHP脚本,用于自动解压和扫描位于外部USB驱动器上的tar.gz归档文件,但我遇到了一些奇怪的问题。一旦脚本定位到一个归档文件,它会尝试在USB驱动器上创建一个临时目录来进行解压缩。为了确保唯一的临时目录名称(因为此脚本可能同时运行多次),我使用当前时间MD5的随机5位数字作为文件名,如下所示: $temp = "/media/$driveName/".substr(md5(microtime()), rand(0, 26), 5);
由于USB驱动器没有挂载到服务器文件系统中,我无法使用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()将其限制为正确的长度,但无济于事),而且无论初始五个字符是什么(在初始五个字符和斜杠之间的字符始终是一个字母但是随机的),其后面的一系列字符总是相同的。除此之外,我束手无策。
2.由于某种原因,我在脚本末尾使用的shell_exec("rm -rf $temp")仅在执行两次时才起作用。如果只执行一次,我会得到以下错误:rm: cannot remove '/media/FILESYSTEM/f3637': Directory not empty,这本身就很奇怪,因为-rf应该覆盖此错误。这种行为也可以在服务器的命令提示符中复制。

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

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

2个回答

0
原来这三个问题都有同样的解决方案:将临时存档文件放在除了USB驱动器以外的其他地方。我不知道是什么原因导致了额外的字符,但当我将临时目录位置移动到Linux的/tmp目录时,它们就一劳永逸地消失了。

0
对于问题1,似乎有一些奇怪的字符混进去了。
我在我的机器上尝试了一下,好像可以正常工作:
<?php

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

我将变量从引号内分离出来,并用 '.' 添加回去。

-Ken


问题在于我需要能够将临时目录的名称保存到一个变量中(我可以使用终端命令找到它,但这似乎是不必要的迂回)。我已经尝试过这样做:shell_exec("mkdir " . $temp); 但好像没有什么区别。 - NinjaBlob
你能直接输出$temp变量吗?我猜里面可能有一些非ASCII字符。 - Ken Koch
我尝试了,但仍然遇到了同样的问题:ob_start(); echo $temp; $temp = ob_get_clean(); - NinjaBlob
对于误解感到抱歉!这是一些输出:/media/FILESYSTEM/1a8b7/media/FILESYSTEM/df32b。然而,即使没有您链接的脚本,输出也是这样的;当我将$temp传递给shell_exec()时,即使它不是一次性的,$temp的值总是正常显示,当我回显它时。 - NinjaBlob
服务器托管在自定义的Linux内核上;我通过Windows访问它,但是脚本本身应该完全在Linux上执行。另外,我在原始帖子中添加了一些信息。 - NinjaBlob
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接