php执行system()命令和一个坑
一部分的内容需要涉及linux的操作,我本是比较喜欢使用 system($cmd[,$res]) 函数来操作linux系统命令。
因为它能够像写shell脚本一样,通过$res来判断上一步是否操作成功。
(PHP操作linux命令前提是已经关闭了safe_mode,或者是将disabled_method中的相关函数释放出来)
一、需求
昨天在做一个测试的时候,需要将以已经存在的文件进行重命名(结合时间戳),然后创建新的文件,然后在进行一步其他的操作,最终会生成一个新的文件
上面的需求中第二部其他操作存在操作的失败性质,如果第二部操作失败了,则需要回滚操作,将之前重命名的结果返回来。
上面的操作是在linux进行的定时任务,关于定时任务结合php在结合linux我会再写一篇文章
二、代码
其实这部分的代码是很简单的,摘出来放在下面,主要流程是:
- 从数据库中获取一个数组信息
遍历数组执行一系列操作:
- 将文件名进行重命名
- 通过操作生成新的文件(这一步存在失败的可能)
- 如果操作失败,回滚第一步操作,恢复原来的文件。
for($i=0;$i<$countAllRoom;$i++){
// 从配置中获得ffmpeg截图存放位置
$photoPos=Config::get('ffmpeg.photoPos');
// 获得时间戳文件名
$fileStamp=$allRoomIGuid[$i]['guid']."_".time();
// 重命名原来的文件 结合timestamp
$cmd=" mv ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png ".$photoPos."/".$fileStamp.".png";
// echo($cmd);
$result=system($cmd,$res);
echo $res."-";
// 从配置中获取视频流
$rtmpUrl=Config::get('view_replace_str.__RTMP_URL__');
/**
* 拼接ffmpeg命令行
* - 下面命令表示从 rtmp://192.168.124.129/myapp/10000 视频流的2秒后切一个图
* - 存放名称路径是下面的代码
*/
$cmd="ffmpeg -i ".$rtmpUrl."/".$allRoomIGuid[$i]['guid']." -f image2 -ss 1 -vframes 1 -s 400*300 ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png ";
// 使用system函数执行系统命令
// echo $cmd;
$result=system($cmd,$res);
echo $res."-";
if($res==1){
// 如果执行失败 则说明没有生成新的文件,讲原来的mv操作撤销
$cmd=" mv ".$photoPos."/".$fileStamp.".png ".$photoPos."/".$allRoomIGuid[$i]['guid'].".png";
system($cmd,$res);
echo $res."-";
}
}
上面的代码是逻辑的一部分,第二部操作是通过ffmpeg从视频流中截取一个截图,存在在/.../live/路径下,文件名都是固定的格式,从数组中获取。
ffmpeg在截取的时候可能会失败,因此需要通过$res进行判断,如果失败了(shell中0代表成功,非0代表失败),则将重命名的内容再恢复。
三、问题
上面的逻辑没有问题,但是在实际操作的时候,发现一直无法正确实现。
mv 命令都无法实现,不过ls这样的命令是可以实现的。
- 后面发现是 live文件夹的权限是755,这个文件都是使用root用户创建的。
- 我安装apache是apache2.4,操作用户是www,所以原因也比较明朗,用户权限不足,无法对文件进行操作。
四、后记
比较粗暴的做法是*直接给live文件夹 777的权限。
比较好的做法是给www用户相关的文件操作权限。
如果发现返回的结果是127,则是说明www用户没有操作脚本的权限,应该给予www用户bash权限
$ usermod -s /bin/bash www
文章版权:Postbird-There I am , in the world more exciting!
本文链接:http://www.ptbird.cn/php-system-problem.html
转载请注明文章原始出处 !